<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[StyleShare - Medium]]></title>
        <description><![CDATA[스타일쉐어의 모든 과정을 기록합니다. 공동 저자가 될 멋진 동료를 기다리고 있습니다. join@styleshare.kr - Medium]]></description>
        <link>https://medium.com/styleshare?source=rss----ed9cf866ec01---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>StyleShare - Medium</title>
            <link>https://medium.com/styleshare?source=rss----ed9cf866ec01---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 11:44:10 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/styleshare" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[사용자 조사로 첫 화면에 의미있는 개선 만들기]]></title>
            <link>https://medium.com/styleshare/%EC%82%AC%EC%9A%A9%EC%9E%90-%EC%A1%B0%EC%82%AC%EB%A1%9C-%EC%B2%AB-%ED%99%94%EB%A9%B4%EC%97%90-%EC%9D%98%EB%AF%B8%EC%9E%88%EB%8A%94-%EA%B0%9C%EC%84%A0-%EB%A7%8C%EB%93%A4%EA%B8%B0-ef823b6c4b6c?source=rss----ed9cf866ec01---4</link>
            <guid isPermaLink="false">https://medium.com/p/ef823b6c4b6c</guid>
            <category><![CDATA[growth-hacking]]></category>
            <category><![CDATA[user-research]]></category>
            <category><![CDATA[product-design]]></category>
            <category><![CDATA[ux-design]]></category>
            <dc:creator><![CDATA[Seulgi Ji]]></dc:creator>
            <pubDate>Mon, 11 Jan 2021 12:00:28 GMT</pubDate>
            <atom:updated>2021-01-13T13:16:06.019Z</atom:updated>
            <content:encoded><![CDATA[<p>얼마 전 스타일쉐어 서비스 첫 화면인 홈에 ‘브랜드 랭킹’ 이라는 컴포넌트를 선보였습니다. 브랜드 랭킹 컴포넌트는 기존에 브랜드를 보여주던 방식을 개선하고 우리가 타겟하는 1020 신규 유저들에게 가치 있는 제안을 하기 위해 만들어졌습니다. 브랜드 랭킹은 A/B테스트로 효과를 검증했는데, 예상보다 훨씬 압도적인 퍼포먼스를 보여주어 데이터를 보던 저희 스쿼드 구성원 모두 깜짝 놀랐습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cSHsSeAtWWRXyzv24psixA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1AFmmn83rcBopgVy9jAi9A.png" /></figure><p>브랜드 랭킹은 기존 대비 29배의 성장을 만들었습니다. 브랜드 랭킹이 100번 노출 됐다면 약 80번의 클릭이 만들어집니다. 그 다음 퍼널인 브랜드 상세 페이지로 이동하는 유저는 브랜드 랭킹을 본 유저 중에 약 22% 입니다.</p><p>워낙 성과가 좋다보니 과장된 결과가 아닌지 검토하는 과정을 거쳤습니다. 첫 번째로 단지 ‘변화’ 했다는 것 때문에 유저들이 신기해서 눌러본 것은 아닌지 알아보았습니다. 기존 컴포넌트에 노출된 적 없는, 즉 컴포넌트가 변화한 것을 모르는 신규 사용자를 대상으로 샘플링해본 결과, 전체 실험 결과와 같았습니다. 두 번째로 일시적인 현상인지 알아보기 위해 데일리 실험 데이터와 실험 종료 후의 퍼포먼스를 살펴봤습니다. 그 결과, 실험 기간 동안 데일리 퍼포먼스는 전체 퍼포먼스와 비슷했고, 실험을 종료한 이후에도 브랜드 랭킹은 실험 때와 마찬가지로 좋은 성과를 보였습니다.</p><p>기존 컴포넌트에 비해 다양한 카테고리, 3개에서 5개로 늘어난 브랜드 리스트 등 클릭이 많이 일어날 수 밖에 없는 구성이라 더 좋은 퍼포먼스가 나온 것도 있지만, 다양한 카테고리에서 많은 사람들의 사랑을 받는 브랜드를 알고 싶은 유저들의 관심이 가장 큰 요인이라 생각됩니다.</p><h3>사용자 조사</h3><p>브랜드를 향한 유저들의 갈증을 어떻게 캐치했을까요? 제목을 통해서 짐작하셨겠지만 바로 사용자 조사입니다. 저희는 스쿼드로 조직된 지난 10월, 모든 스쿼드 구성원이 참여해 스타일쉐어를 쓰지 않는 1020 여성들을 인터뷰 했습니다. (*모든 인터뷰는 방역 수칙을 준수하여 진행되었습니다.)</p><p>저희 스쿼드는 서비스 첫 화면인 홈으로 신규 유저의 잔류와 재방문 지표를 개선해야 한다는 목표가 있었습니다. 저희는 신규 유저들이 왜 스타일쉐어를 길게 쓰지 않는지, 왜 다음에 다시 오지 않는지, 그렇다면 무엇을 원하는지에 대한 이해와 공감이 필요했고, 이는 데이터만으로는 알지 못했습니다.</p><h4>데이터는 모든 것을 말해주지 않는다</h4><p>실제로 저희는 홈을 방문하고 잔존한 유저, 그렇지 않은 유저의 사용성에 차이가 있을 것이라는 가설을 세우고 데이터를 확인 했습니다. 당시 홈은 일부 신규 유저에게만 보여지는 실험적인 페이지였기에 서비스 첫 화면이 홈이 아닌 인기 피드인 유저도 있었는데요.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZO2Sj3XmC6kyf2HbYrtsDw.png" /><figcaption>신규 사용자가 볼 수 있는 화면 두 가지. 홈 (좌측) 과 인기 피드 (우측)</figcaption></figure><p>더 정확히 알아보기 위해 홈을 방문하고 잔존한 신규 유저 (Group A), 인기 피드를 방문하고 잔존한 신규 유저 (Group B), 홈을 방문하고 이탈한 신규 유저 (Group C), 인기 피드를 방문하고 이탈한 신규 유저 (Group D) 이렇게 4개의 그룹으로 나누고 Behavior에 대한 데이터를 확인 했었습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qFUgUcjGcsGZaRKnLdCUcw.png" /></figure><p>그러나 별 다른 소득이 없었습니다. 대체로 신규 유저들이 하는 행동은 기존 유저들이 하는 행동과 크게 다르지 않았습니다. 홈을 첫 화면으로 보는 유저가 인기 피드를 첫 화면으로 보는 유저보다 더 잔존 비율이 높긴 했지만, Behavior 측면에서는 큰 차이가 없었습니다. 인사이트를 얻기 위해서는 outlier가 있거나 사용성에 큰 차이가 두드러져야 하는데, 그런 경향성은 찾기 힘들었습니다. 모든 유저들이 검색을 하고, 스타일을 보고, 상품을 눌렀습니다. 약간의 빈도 차이는 있었지만, 그 차이가 크지 않아 의도를 추측하기 어려웠습니다.</p><p>어떤 게 궁금해서 검색을 했을까? 우리 앱에서 무엇을 보고 검색을 했을까? 만약 우리 앱이 아닌 다른 곳에서 봤다면 거긴 어딜까? 데이터는 우리 제품 위에서만 쌓이기 때문에 유저의 의도와 생각을 알려주지 못했습니다. 이런 문제 의식을 바탕으로 평소 사용자 조사에 관심이 많았던 안드로이드 개발자 한 분이 사용자 조사를 제안하셨습니다. 그리고 저희 스쿼드가 조직된 첫 kick-off 미팅 날, 20대였던 제 동생을 바로 리쿠르팅해 당일 저녁에 인터뷰를 진행 했습니다. 이를 계기로 다양한 1020 사용자를 만나며 저희의 사용자 조사가 시작 되었습니다.</p><h4>사용자 조사 인사이트</h4><p>사용자 조사로 저희는 20대 고객들이 ‘브랜드’를 중심으로 패션, 뷰티를 인식하고 탐색한다는 인사이트를 얻을 수 있었습니다. 20대 고객들에게는 ‘믿고 사는 브랜드’ 또는 ‘좋아하는 브랜드’가 최소 한 두 가지씩 있었습니다. 단지 품질을 보장하기 때문이 아니라 브랜드가 추구하는 색깔과 이미지가 자신의 취향과 잘 맞기 때문에 브랜드를 좋아하고 있었습니다. 브랜드를 인터페이스 삼아 자신의 취향을 소비하고 강화하고 있었죠. 유저가 새로운 브랜드를 알게 된다는 것은 ‘살만한 것’을 알게 되는 것을 넘어 새로운 ‘취향’을 습득하는 것이라 생각했습니다. 그리고 우리 플랫폼에는 유저와 만나고 싶은 수많은 브랜드가 있으니, 유저에게 브랜드를 잘 보여주는 것은 서로에게 win-win이겠죠.</p><h4>제품화</h4><p>그래서 유저에게 브랜드를 어떻게 제안할지 고민했습니다. 기존에도 브랜드를 보여주는 컴포넌트가 있었지만 반응이 저조 했는데요. 브랜드의 멋진 상품 이미지를 보여줬지만 ‘지금 뜨는’ 이라는 모호한 기준은 유저에게 메리트가 없었던 것 같습니다. 믿을 만한 기준으로 제안하는 게 필요했죠. 그래서 ‘인기순 (랭킹)’ 이라는 기준을 선택했습니다. 많은 사람들에게 인기가 있다 라는 Social Proof는 이미 서비스 내 여러 방면에서 성과가 증명됐습니다.</p><p>그리고 이 랭킹은 전체 브랜드를 대상으로 한 랭킹이 아닌 ‘카테고리’ 내에서의 랭킹을 보여주기로 했습니다. 이는 사용자 조사에서 유저들이 ‘뷰티 브랜드’, ‘운동화 브랜드’ 같이 카테고리를 키워드 삼아 브랜드를 인식하고 있음을 발견한 덕분인데요. 유저들에게는 패션에서 좋아하는 브랜드, 뷰티에서 좋아하는 브랜드, 주얼리에서 좋아하는 브랜드가 다 따로 있었습니다. 서로 다른 카테고리를 가진 브랜드 사이의 랭킹 보다는 같은 카테고리를 가진 브랜드 사이의 랭킹이 더 의미 있을 거라 생각했죠. 뷰티 브랜드인 롬앤, 종합 패션 SPA 브랜드인 스파오, 풋웨어 브랜드인 닥터 마틴 사이의 순위 보다는 뷰티 브랜드인 롬앤, 클리오, 에스쁘아 사이의 순위가 더 흥미로운 것 처럼요.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ufeBPkCBN545B1iFO8Smjw.png" /><figcaption>모든 브랜드 랭킹과 특정 카테고리의 브랜드 랭킹 비교. 위 이미지는 예시 이미지로 실제 랭킹과 무관합니다.</figcaption></figure><p>또, 카테고리 랭킹으로 보여줄 경우 전체 랭킹으로는 볼 수 없는 새로운 브랜드를 만날 가능성도 높아집니다. 실제로 카테고리 랭킹 로직의 유효성을 판단하기 위해 실험 전, 내부에서 중간급 카테고리 (e.g. 후드/집업, 스니커즈, 스킨케어)의 랭킹을 뽑았었는데요. 몰랐던 브랜드를 알게 되기도 했고, 이름은 들어봤으나 이해도가 낮았던 브랜드의 새로운 면모를 발견할 수도 있었습니다.</p><blockquote><em>“이 브랜드, 유저들 사이에서 입소문 도는 건 봤는데 실제 랭킹에서도 N등을 하고 있네? 생각보다 인기 있나보다.”<br>“이 브랜드 이름은 처음 들어보는데 스킨 케어에서 N등을 하고 있네?”</em></blockquote><p>이런 생각이 드니 카테고리 브랜드 랭킹이 꽤 잘 되겠다는 확신이 들었습니다.</p><h3>제품과 결과</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*grFyl2Sx8sQX0a1q4yc2Bg.png" /></figure><p>이러한 과정 끝에 브랜드 랭킹 컴포넌트가 탄생했습니다. 새로운 브랜드 랭킹 컴포넌트는 기존 브랜드 컴포넌트와 달리 사람들에게 인기 있는 것을 보여준다는 Social Proof를 제공하고, 또 전체 브랜드 랭킹이 아닌 카테고리별 브랜드 랭킹으로 다양한 영역에서 사람들에게 사랑받는 브랜드를 제안합니다. 매일 랭킹의 순위가 바뀌기 때문에 첫 등장 이후에도 지금까지 좋은 퍼포먼스를 보여주고 있습니다. 대개 브랜드의 핵심 자산이라고 여겨지는 상품 사진을 보여주지 않음에도 상품 사진을 보여줬던 기존 컴포넌트 보다 더 좋은 퍼포먼스를 보여주고 있고요.</p><p>서비스 내에 브랜드, 랭킹, 카테고리라는 자산이 모두 있었기 때문에 조합하다보면 나올 수 있는 결과라는 차가운 시선이 있을 수도 있겠습니다. 그러나 이 결과를 만나기 전 성공하든 실패하든 배움이 있을 것이란 확신, 브랜드 탐색 경험을 개선해야 한다는 방향성은 사용자 조사가 있었기 때문에 나올 수 있었습니다. 데이터만 들여다 봤으면 알지 못했을 브랜드에 대한 유저들의 인식, 구분 등을 사용자 조사를 통해 배웠기 때문이지요.</p><h3>마치며</h3><p>짧은 글로 저희의 긴 과정을 담으니 마치 모든 것이 매끄럽게 맞아 떨어진 것 처럼 보입니다. 그러나 스타트업이 그러하듯, 제품 만드는 사람들이 그러하듯 저희의 과정도 순탄치 않았습니다. 인터뷰도 펑크는 기본, 서울 강남에서 경기도 이천으로 인터뷰도 갔었고요. 사용자 인터뷰에 익숙하지 않아 벼락치기 식으로 공부도 해야 했습니다. 어떻게 물어봐야 원하는 것을 얻을 수 있을지 노하우가 없다보니 급하게 전문 리서처 분을 모셔 여쭙는 시간도 가졌었습니다. (흔쾌히 시간을 내주신 김은희 님, 정말 감사합니다!) 그리고 사용자 조사로 쌓인 input을 인사이트로 만들고, 기획으로 만들고, 제품으로 만들기 위해 머리 싸매고 회의 하는 시간도 많았고요.</p><p>저희 스쿼드 구성원 모두 이 과정에 전문가가 아니었기 때문에 두려움이 있었습니다. 이대로 고생은 고생대로 하고 인사이트 없이, 제품 변화 없이 끝나면 어쩌지? 두려움을 한 방에 날린 멋진 기회는 없었지만 작게나마 확신을 얻은 모먼트들이 있었습니다. 많은 인터뷰 끝에 유저의 입장을 이해하고 몰입하고 있음을 느낀 순간, 함께 인터뷰한 동료들이 그것에 공감하는 순간, 중간 카테고리의 브랜드 랭킹을 뽑아 확인한 순간 등등이요.</p><p>굳이 얘기하지 않아도 될 백스테이지의 초라한 모습을 적었습니다. 읽으신 분들께서 더 마음 편하게 사용자 조사를 시도하셨으면 하는 마음 때문입니다. 저희도 이제 한 발자국 내딛었습니다. 사용자 조사를 바탕으로 개선해야 할 부분은 쌓여있고, 브랜드와 관련된 가치있는 제안도 더 많이 시도해야 합니다. 사용자 조사도 끝이 아니고요. 운 좋게 첫 아이디어가 멋지게 성공해 글을 썼지만, 또 다시 글을 쓸 땐 실패기로 돌아올 수도 있겠습니다. 제품 만드는 과정은 매끄러워서는 안된다고 합니다. 이 글로 공유한 저희의 거친 과정이 다른 분들의 시도에 도움이 되었으면 좋겠습니다.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ef823b6c4b6c" width="1" height="1" alt=""><hr><p><a href="https://medium.com/styleshare/%EC%82%AC%EC%9A%A9%EC%9E%90-%EC%A1%B0%EC%82%AC%EB%A1%9C-%EC%B2%AB-%ED%99%94%EB%A9%B4%EC%97%90-%EC%9D%98%EB%AF%B8%EC%9E%88%EB%8A%94-%EA%B0%9C%EC%84%A0-%EB%A7%8C%EB%93%A4%EA%B8%B0-ef823b6c4b6c">사용자 조사로 첫 화면에 의미있는 개선 만들기</a> was originally published in <a href="https://medium.com/styleshare">StyleShare</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[우리는 코드 리뷰를 잘하고 있을까요?]]></title>
            <link>https://medium.com/styleshare/%EC%9A%B0%EB%A6%AC%EB%8A%94-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0%EB%A5%BC-%EC%9E%98%ED%95%98%EA%B3%A0-%EC%9E%88%EC%9D%84%EA%B9%8C%EC%9A%94-201c12d04d0d?source=rss----ed9cf866ec01---4</link>
            <guid isPermaLink="false">https://medium.com/p/201c12d04d0d</guid>
            <category><![CDATA[개발문화]]></category>
            <category><![CDATA[develop]]></category>
            <category><![CDATA[스타일쉐어]]></category>
            <category><![CDATA[engeneering]]></category>
            <category><![CDATA[코드리뷰]]></category>
            <dc:creator><![CDATA[develog]]></dc:creator>
            <pubDate>Mon, 19 Oct 2020 08:50:26 GMT</pubDate>
            <atom:updated>2020-11-05T01:41:59.681Z</atom:updated>
            <content:encoded><![CDATA[<p>안녕하세요, 스타일쉐어에서 안드로이드 개발을 맡고 있는 <strong>이길현 개발자</strong>라고 합니다.<br>여러분들은 코드 리뷰에 대해서 어떻게 생각하시나요? 현재 코드 리뷰를 잘하고 계신가요?</p><p>제가 거쳐온 회사들은 코드 리뷰 정책이나 문화가 모두 달랐어요. 첫 회사는 PR이란 개념이 아예 없었는데 신뢰라는 변명 아래 일단 머지하고 보는 식이었죠. 충돌이 발생하거나 궁금한 것이 생기면 메신저나 오프라인으로 찾아가서 물어보는 방식이었어요.</p><p>한 회사에서는 제가 작성한 코드를 배포하기 위해 리뷰를 필수로 거쳐야 했지만, 코드에 대한 피드백 없이 단순히 코드 베이스의 변경을 확인하는 정도에 그쳤어요.</p><p>이전 회사에서의 경험과 달리 스타일쉐어에서는 PR을 작성하고 코드 리뷰를 하는 데 매우 공을 들이고 있어요. 때로는 동료분이 작성한 코드를 리뷰하느라 하루를 보낸 적도 있었고, “이런 작은 것까지 수정 요청을 주고받는 게 맞는 걸까?”라는 생각이 들 때도 종종 있었고요. 코드 리뷰에 대한 고민이 많은 팀이기에 코드 리뷰를 잘하는 다른 조직의 이야기가 궁금하더라고요.</p><p><strong>[백명석님의 초청 강연]</strong></p><p>그러던 중 코드 리뷰에 대한 이야기를 들을 기회가 생겼어요. 사내에서 스타일쉐어와 29CM 개발팀을 위해 종종 연사를 초청해 강연을 부탁드리는데요, 이번엔 CTO님 찬스로 11번가에 계신 백명석님을 초청해 코드 리뷰를 주제로 많은 이야기를 들을 수 있었어요.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/370/0*sS2sAKXZMn2IZBSq" /></figure><p>백명석님은 이전부터 <a href="https://brunch.co.kr/@cleancode">브런치</a>, <a href="https://www.youtube.com/user/codetemplate/videos">유튜브</a> 등 미디어에서 소프트웨어 공학을 주제로 다양한 글과 영상을 작성해오셨는데요, 11번가라는 큰 조직에서 풍부한 경험을 토대로 어떻게 코드 리뷰 문화를 리드하고 있으신지 들을 수 있는 강연이었습니다.</p><p>제 주관적인 입장에서 기억에 남았던 몇 가지 이야기들을 요약했습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/940/0*Akz_Gkm5ktuyPMUs" /></figure><p><strong>[왜 코드 리뷰를 해야 할까요?]</strong></p><p>강연 도입부에서 코드 리뷰를 왜 해야 하는지에 대한 이야기를 들을 수 있었어요. 시장은 항상 변하기 마련이라 비즈니스는 복잡하고 불확실하며 예측할 수 없는데요, 변화하는 시장에 맞춰 더 빨리 비즈니스를 전개해야만 한다고 해요. 그러기 위해 소프트웨어는 더 자주, 신속하게, 신뢰성 있게 전달되어야 하죠. 결국 비즈니스는 소프트웨어의 생산성과 직결되어 있습니다.</p><p>개발자들이 많아진다고 생산성이 선형적으로 증가하지 않는다는 것은 많은 분이 알고 계실 거예요. 사람이 많아질수록 커뮤니케이션에 점점 더 큰 비용을 사용하기 때문이지요. 비슷하게, 릴리즈하면 할수록 개발 비용은 점점 증대하게 되고 생산성은 점점 저하되는 현상이 나타납니다. 릴리즈를 거듭할수록 소프트웨어가 점점 거대해지거든요.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/940/0*AgP9f8VSWDXl0-kE" /><figcaption>출처: 클린 아키텍처</figcaption></figure><p>소프트웨어가 거대해지더라도 생산성을 유지하기 위해서는 좋은 아키텍처, 좋은 코드, 좋은 설계가 동반되어야 해요. 코드 리뷰는 이를 위한 일종의 검수 과정인데요, <strong>새로 작성되는 기능이 버그가 없고 의도대로 동작하는 것을 확인하는 것은 물론이고 약속한 아키텍처를 잘 따르고 있는지, 다른 사람이 읽는 데 문제가 없는 코드인지, 올바르게 설계되었는지 확인하는 과정</strong>이기도 해요.</p><p>코드 리뷰는 소프트웨어 공학 관점에서 볼 때 이처럼 코드의 품질과 생산성을 유지하기 위해서도 필요하지만 다른 부수적인 효과도 있다고 해요. 리뷰를 통해 <strong>코드에 대한 피드백을 주고받으면서 팀 전체가 성장할 기회</strong>가 되기도 하는데, 가령 누군가 잠재적인 위험이 있는 코드를 작성한다면 리뷰어는 해당 코드에 대한 문제점과 해결책을 제시하고 작성자는 자신이 몰랐던 새로운 사실에 대해 알게 되겠죠.</p><p>또한 리뷰 과정을 통해 코드가 작성자 한 사람에게 의존되거나 혼자만 책임지는 것이 아닌 <strong>팀 전체가 기여하고 오너십을 발휘하는 기반</strong>이 되기도 해요.</p><p><strong>[코드 리뷰가 잘 안 돼요. 왜죠?]</strong></p><p>강연에서 코드 리뷰가 어려운 이유를 들을 수 있었는데요. 강연을 들으면서 예전의 제 모습이 떠올라 많이 공감되고 웃을 수 있던 시간이었어요.</p><p>코드 리뷰는 작성자와 리뷰어가 지식과 경험을 공유하고 토의하며 상호 학습을 통해 성장할 좋은 기회이지만, 이 과정에서 피드백의 방향에 따라 작성자가 개인에 대한 공격으로 받아들이게 되면 토의가 이루어질 수 없게 돼요.</p><p>예를 들어 일반적으로 작성자는 본인 생각에 멋지다고 생각하는 코드를 작성하지만, 정작 리뷰어는 멋지지 않다고 생각할 수 있죠. 그런 경우 리뷰어가 혹여라도 피드백을 잘못하게 되면 그 과정에서 작성자는 코드에 대한 비판을 자신에 대판 비판으로 받아들이는 경우가 있을 수 있다고 해요.</p><p>생각을 글로 전달하는 것도 어려운 요소 중 하나에요. 직접 얼굴을 맞대어 대화하는 것과 달리 상대방의 음성 톤과 표정을 알 수 없기 때문에 오해의 위험이 크기 때문인데요, 그래서 피드백을 주고받을 땐 상대방이 오해하지 않도록 조심스럽게 표현하는 것이 중요하다고 합니다.</p><p>예를 들어, “File 객체의 close() 메소드 호출을 빠뜨렸어”라고 피드백을 하면 “어떻게 File 객체를 쓰는데 close() 호출을 깜빡할 수가 있어?” 라고 받아들일 수도 있다고 하네요.</p><p><strong>[코드 리뷰를 잘하기 위한 기법들]</strong></p><p>코드 리뷰가 잘 자리 잡고 진행되기 위해서는 방해되는 요소는 제거하고 자연스럽게 리뷰를 진행할 수 있는 환경을 만드는 것이 중요한데요. 강연에서는 이런 환경을 만들기 위한 기법들 몇 가지를 소개했어요. 그중에서도 기억에 남는 몇 가지를 정리했습니다.</p><p><strong>지루한 작업은 자동화</strong></p><p>가장 먼저 소개한 것은 공백이나 들여쓰기 같은 지루한 작업은 직접 하지 말고 <strong>자동화된 도구</strong>를 사용하자는 것이었어요. 이런 지루한 작업은 기계가 더 잘하고 다른 사람이 작성한 코드를 읽는 것 자체가 높은 집중력이 요구되는 작업이기 때문에 노력을 낭비하지 말고 정말로 필요한 문제에만 집중해야 한다는 이야기였어요.</p><p><strong>스타일 가이드 정립</strong></p><p>스타일은 가이드를 정해서 따르고 PR에서 논쟁하지 말자는 것이었어요. 코드 리뷰에서 스타일에 대한 논쟁은 시간 낭비이기 때문인데요, 일반적으로 스타일 가이드를 정하는 방법은 아래 세 가지 중 한 가지를 선택한다고 해요.</p><ul><li>이미 존재하는 잘 정의된 스타일 가이드를 적용하기</li><li>점진적으로 스타일 가이드를 만들기</li><li>위 두 가지를 혼합하기</li></ul><p><strong>즉시 리뷰</strong></p><p>작성자는 리뷰가 완료될 때까지 다음 작업에 온전히 집중할 수가 없는 상태가 되는데요, 리뷰를 기다리거나 컨텍스트 스위칭을 감당하며 다른 작업을 하게 되는데 결과적으로 리뷰가 늦어질수록 PR 작성자의 생산성에 큰 영향을 받게 됩니다. 이는 팀의 생산성에도 영향을 주기에 코드 리뷰는 가능한 한 빨리 완료되어야 해요.<br>빠른 리뷰를 위해 PR의 범위가 작고 단순하게 만들고, 이를 통해 개발자가 효율적으로 일할 수 있는 선순환 구조를 만드는 것이 중요하다고 해요.</p><p>일반적으로 리뷰를 주고받는 시간이 하루가 넘어가면 안 된다고 합니다. 리뷰가 지체되면 다른 리뷰어를 지정하는 등 빠르게 리뷰가 이루어질 수 있도록 조치해야 하고, 리뷰어가 빈번하게 변경되지 않도록 건강한 개발 사이클을 유지할 수 있도록 해야 합니다.</p><p><strong>고수준으로 시작해서 저수준으로 진행</strong></p><p>한 번에 너무 많은 의견을 남기면 PR 작성자는 당황할 가능성이 커집니다. 그래서 처음엔 인터페이스 설계나 복잡한 함수 분리 등 고수준의 피드백을 먼저 남기고, 이후에 변수 이름이나 주석 등 낮은 수준의 피드백을 남기는 것이 좋다고 해요.</p><p><strong>피드백은 명령이 아닌 요청으로</strong></p><p>현실에서 동료에게 명령하는 사람은 없을 거예요. 다만 리뷰 과정에서 글로 남겨지는 코멘트는 종종 명령처럼 보이기도 하는데요, 작성자가 명령이 아닌 권유나 요청으로 느껴질 수 있도록 표현해야 해요. (한국말은 아 다르고 어 다르다고 하잖아요) 예를 들어 “Foo 클래스를 분리하세요”보다는 “Foo 클래스를 분리하는 건 어떨까요?”나 “Foo 클래스를 분리할 수 있을까요?” 처럼 부드러운 표현을 사용하는 것이 좋다고 하더라고요.</p><p><strong>원칙에 기반한 피드백</strong></p><p>변경을 요청할 때에는 반드시 제안과 근거가 있어야 해요. 어떻게 바뀌길 바라는지, 왜 그렇게 바꿔야 하는지 객관적인 사실과 원칙에 기반해 피드백을 해야 작성자도 설득이 되고 요청을 받아들일 수 있겠죠. 앞뒤 잘라서 “Foo 클래스의 일부를 Bar 클래스로 분리해야 해요.” 보다는 “Foo 클래스는 읽기와 파싱 두 가지 책임을 갖고 있으니 두 클래스로 분리해 SRP 원칙을 준수해야 해요.”라고 제시하는 것이 훨씬 더 작성자를 설득하기 수월할 거예요.</p><p><strong>재미있는 건 소프트웨어는 공학이면서도 예술에 가까워서 항상 원칙에 기반해 정확히 무엇이 잘못되었는지 언급할 수 있는 건 아니라고 하더라고요.</strong> 단순히 그냥 보기 싫거나 눈에 보이지 않는 코드가 있을 수도 있는데 객관적으로 단순히 이해하기 어렵다고 이야기하면 충분하다고 합니다.</p><p><strong>조금씩 좋아지기를 기대</strong></p><p>엉클 밥으로 유명한 로버트 마틴조차도 “나는 처음부터 깨끗하게 작성한 것이 아니다. <strong>“누구도 처음부터 깨끗한 코드를 작성할 수 없다고 생각한다”</strong>라고 말했어요. 한 번에 완벽한 코드를 만들 수 있는 사람은 없다는 거죠. 그러므로 리뷰를 하는 코드가 D등급이라면 리뷰 후 A등급의 코드가 되기를 기대하기보다는 C, B등급의 코드가 되도록 기대하고 도와야 한다고 해요.</p><p>작성자와 리뷰어가 여러 차례 피드백을 주고받으면서도 코드의 승인이 보류되는 유일한 이유는 기능적인 문제나 동작의 정합성을 보장할 수 없을 때가 유일하고, 그 외에는 완벽하진 않아도 더 좋은 코드가 되도록 하는 것이면 충분하다고 합니다.</p><p><strong>리뷰 범위 지키기</strong></p><p>의외로 자주 저지르는 실수 중 하나가 변경된 코드 근처의 코드를 작성자에게 수정 요청하는 경우라고 해요. PR과 전혀 무관한 코드지만 변경된 코드를 비교해 표시되기 때문에 무의식적으로 작성자가 작성하지 않은 코드에 대한 수정을 요청하는 경우가 많아요.</p><p>단, 만약 변경하지 않은 코드가 PR에서 변경한 코드에 영향을 미치는 경우에는 예외적으로 리뷰어가 작성자에게 수정을 요청할 수 있어야 한다고 합니다.</p><p><strong>칭찬하기</strong></p><p>대부분이 코드 리뷰할 때 코드의 좋은 점보다는 잘못된 부분을 찾는 것에만 집중합니다. 리뷰 대상이 되는 코드에서 더 좋은 코드로 개선하거나 잘못된 것을 찾겠다는 생각에 휩싸여 놓치는 것 중의 하나인데요. 분명 다른 사람의 코드를 보면서 몰랐던 것을 알게 되거나 새로운 사실을 배우게 되는 경우도 많을 거예요. 예를 들면 새로운 API를 알게 되었다거나, 어려운 문제를 쉽게 만들어 해결한다거나, 훨씬 좋은 구조를 만들어낸다거나 하는 것들이요.</p><p>이런 따뜻한 피드백은 리뷰어가 코드를 검사하는 감시자나 허락을 구해야 하는 존재가 아니라 진심으로 도와주려는 팀 동료라는 인식을 하게 해 줄 수 있습니다.</p><p><strong>교착 상태 해결하기</strong></p><p>코드 리뷰에서 최악의 결과는 교착 상태인데요. 여기서 교착 상태는 작성자는 리뷰어의 의견을 반영하기를 거부하고, 리뷰어는 의견이 반영되지 않았으니 승인하지 않는 상황을 말합니다.</p><p>교착 상태가 발생하면 우선 만나서 이야기를 하는 게 좋다고 해요. 텍스트에 기반한 커뮤니케이션은 서로가 인간이라는 것을 잊게 만들고 오해로 인해 잘못된 커뮤니케이션을 만들 가능성이 높거든요.</p><p>교착 상태가 길어지면 리뷰어와 작성자의 사이가 점점 나빠지게 되는데, 수준 낮은 코드를 승인함으로 발생하는 품질 손해보다 동료와 다퉈서 발생하는 품질 손해가 더 크다고 해요. 가능하다면 어느 한 사람이 인정해 교착을 해결하고 그럴 수 없다면 리더에게 문제를 전달해 다른 리뷰어가 리뷰를 진행할 수 있게끔 만들어야 합니다.</p><p>교착이 발생한 경우엔 매니저, 또는 리더와 상의하고 휴식을 가지는 게 좋다고 해요. 특히 교착을 만들어낸 두 사람이 관계가 회복될 때까지는 서로 코드 리뷰를 요청하지 않도록 해야 한다고 합니다.</p><p><strong>[돌아보며]</strong></p><p>강연에서 소개하신 많은 기법 중에서 우리가 이미 잘하고 있던 것들이 있었어요.</p><p>우리 팀이 정말 잘해왔던 것 중 하나가 <strong>리뷰어를 위해 PR 작성자가 최선을 다한다는 것</strong>인데요, 우리 팀은 PR 템플릿을 정해 그에 맞도록 최대한 상세히 PR을 작성하고 있습니다.</p><ul><li>작성 배경</li><li>주고받았던 논의</li><li>구현 방법</li><li>주의 깊게 봐야 하는 내용</li><li>테스트 방법</li></ul><p>등을 포함하고 가능하다면 한눈에 변경사항을 파악할 수 있는 이미지를 생성해 다음과 같이 PR 본문을 작성하곤 합니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/940/0*di2fkpBtDqBxT_RB" /><figcaption>이 아름다운 PR 템플릿을 보라 (#늘이렇진않아요)</figcaption></figure><p>다음으로는 오늘 강연에서도 나왔던 부분인데 ‘기계가 할 수 있는 리뷰를 사람이 하지 말자’는 부분입니다. 이를 개선하기 전 오랜 기간 동안 코드 포맷 규칙을 작성자가 한땀 한땀 맞춰야 했고 리뷰어도 이를 숙지해야만 했었어요.</p><p>포매팅 때문에 피드백을 주고받는 횟수도 많아지고 리뷰가 길어져 에너지 소모가 심하다는 토로가 있었고, 논의를 통해 자동 포매팅 규칙에 ktlint를 적용한 뒤 포매팅과 관련된 리뷰는 하지 않기로 했어요.</p><p>이후엔 설계, 버그 검출, 좋은 코드에 더 집중해 리뷰할 수 있었고, 오랜 대화를 통해 팀 자체적으로 해결책을 찾았던 터라 강연에서 언급되었던 것이 너무 와닿았어요.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/940/0*R94GNH8-D0GlPjvB" /><figcaption>힘들었던 그때 그 순간</figcaption></figure><p>스타일 가이드와 관련된 부분도 있습니다. 팀 내에선 스타일 가이드를 정해서 따르고 있는데요, 간혹 스타일 가이드에 명시되지 않은 부분을 리뷰할 경우 우선 작성자의 의견을 따르고 별도의 논의를 거쳐 가이드를 업데이트하고 있어요.</p><p>코드에 대한 피드백을 전달할 때에 종종 예제 코드를 보여주기도 합니다. 때로는 문장보다 코드로 설명하는 것이 쉽거든요.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/940/0*iK7YhEc-iTVZUK3y" /><figcaption>따뜻한 코멘트는 기본입니다</figcaption></figure><p>반면, 우리가 잘하지 못했던 것 중 하나가 바로 칭찬하기 아닐까 해요. 코드 리뷰 과정에서 긍정적인 경험을 주는 것이 굉장히 중요한데, 가장 직접적이면서도 쉬운 방법 중인데 왜 이걸 하지 못했을까 하는 생각이 들더라고요.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/940/0*qI5ib9CHV4gWg2ag" /><figcaption>#그래서해봤습니다 #해보니까좋네요 #조작아님</figcaption></figure><p>최근에는 즉시 리뷰 하지 못하고 PR이 점점 쌓여서 팀의 개발 사이클이 좋지 못한 것이 고민이었습니다. 팀 회고를 통해 이를 어떻게 개선할지 논의했고, 일정 수 이상의 PR이 쌓이면 팀원 모두가 하던 것을 즉시 멈추고 리뷰를 우선 하자는 규칙을 정했어요. 강연 막바지 Q&amp;A 시간에 이런 극단적인 규칙이 팀에 도움이 될지 피드백을 부탁드렸는데 굉장히 좋은 방법이라고 하시더라고요.</p><p>강의 이후에 적극적으로 이를 실행하고 있습니다. 리뷰 하지 않은 PR이 10개가 되면 누군가 넛지를 주고 팀 모두가 즉시 리뷰를 진행하고 있어요.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/940/0*blNbt7L-Z-jJ4Y3L" /><figcaption>리.. 리뷰 할게요</figcaption></figure><p>덕분에 아무리 늦더라도 이틀 이내에는 머지가 가능해졌습니다. PR 반장님을 자주 뵙는게 부담이었는지 빠른 개발 싸이클을 경험한 이후부터는 PR이 머지될 때까지 걸리는 시간도 이전보다 눈에 띄게 짧아졌어요.</p><p><strong>마치며</strong></p><p>저는 어느 순간부터 애자일, 페어 프로그래밍, 코드 리뷰라는 단어들을 숨 쉬듯 자연스럽게 접하고 사용했는데 많은 글과 이야기를 들으면서 그저 “좋은 거니까 나도 해야겠네”하고 당연하게 받아들이기만 하고 그걸 왜 해야 하는지는, 하면 뭐가 더 좋아지는지에 대해서는 별로 고민하지 않았더라고요.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/504/0*SSWFSmmsl6aSPBUU" /></figure><p>저는 여러 회사에서의 경험으로 <strong>“코드 리뷰는 시스템보다는 문화다”</strong>라는 생각을 하고 있는데요. 아무리 시스템적으로 코드 리뷰라는 과정이 존재하더라도 실제로 구성원이 적극적으로 참여하지 않으면 그저 불필요한 업무 단계가 하나 더 있는 것으로 인식되는 것을 경험했거든요. 그래서 과거에는 코드 리뷰를 안 하는 사람들을 어떻게 리뷰에 참여하게 할 수 있을까 생각해봤지만 이렇다 할 답을 찾지 못했었어요.</p><p>오늘 들었던 강연에서, 대부분의 개발자가 코드 리뷰가 중요하고 필요하다는 것을 이미 잘 인지하고 있기에 굳이 설득을 하기보다 스스로 하고 싶게 만들어야 한다는 이야기가 인상 깊었어요. 코드 리뷰라는 행위가 하는 사람과 받는 사람 모두에게 이득이 되고 리뷰를 주고받는 행위가 멋지게 느껴진다면 자연스럽게 하고 싶어질 거라고 하시더라고요.</p><p>과거의 저는 같이 일하는 동료들에게 이런 동기를 유발하지 못했고, 저조차도 코드 리뷰를 해야 한다는 강박만 있을 뿐 행동하게 만드는 동기가 없었더라고요. 게다가 스스로 코드 리뷰가 시스템이 아닌 문화라고 정의했으면서도 사람에 대해서 충분히 고려하지 못한 채 규칙, 시스템, 환경 같은 것들만 생각했었어요.</p><p>스타일쉐어에서 일하면서 어느 정도 팀이 이미 코드 리뷰를 잘하고 있었다 생각했지만, 오늘 강연을 통해 코드 리뷰에 대한 추가적인 시각을 접하면서 제가 지금까지 코드 리뷰에 대해 놓치고 있었던 부분, 우리 팀이 잘하고 있거나 부족한 것들이 정리되어 참석하길 잘했다는 생각이 들었습니다.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=201c12d04d0d" width="1" height="1" alt=""><hr><p><a href="https://medium.com/styleshare/%EC%9A%B0%EB%A6%AC%EB%8A%94-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0%EB%A5%BC-%EC%9E%98%ED%95%98%EA%B3%A0-%EC%9E%88%EC%9D%84%EA%B9%8C%EC%9A%94-201c12d04d0d">우리는 코드 리뷰를 잘하고 있을까요?</a> was originally published in <a href="https://medium.com/styleshare">StyleShare</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[fastlane에서 Unexpected Error로 iOS 앱을 제출할 수 없는 문제 해결하기]]></title>
            <link>https://medium.com/styleshare/fastlane%EC%97%90%EC%84%9C-unexpected-error%EB%A1%9C-ios-%EC%95%B1%EC%9D%84-%EC%A0%9C%EC%B6%9C%ED%95%A0-%EC%88%98-%EC%97%86%EB%8A%94-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0%ED%95%98%EA%B8%B0-2c6fd0cd6577?source=rss----ed9cf866ec01---4</link>
            <guid isPermaLink="false">https://medium.com/p/2c6fd0cd6577</guid>
            <category><![CDATA[app-store]]></category>
            <category><![CDATA[fastlane]]></category>
            <category><![CDATA[develop]]></category>
            <category><![CDATA[ios]]></category>
            <dc:creator><![CDATA[전수열]]></dc:creator>
            <pubDate>Wed, 27 May 2020 19:46:30 GMT</pubDate>
            <atom:updated>2020-05-27T20:03:26.611Z</atom:updated>
            <content:encoded><![CDATA[<p>새 버전을 앱스토어에 제출하기 위해 GitHub에 태그를 푸시하고 배포 파이프라인이 실행되기를 기다렸습니다. 하지만 20분간의 빌드가 끝나고 들려온 것은 슬픈 소식이었습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1BXg4akbnOfpAH-W2mOeAg.png" /></figure><p>에러 원인을 확인하기 위해 빌드 로그를 보았지만 Unexpected Error라는 것 외에는 특별히 도움이 되는 정보가 없었습니다. 처음 겪는 문제라, 일시적인 서버 장애라고 생각하고 두어 번을 더 실행해 보았지만 결과는 같았습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NDYXSloVmW6YE359eNIp6Q.png" /></figure><p>예정대로 릴리즈를 내보내기 위해서는 이 문제를 빨리 해결해야 했습니다.</p><h3>정보 수집</h3><p>정확히 어떤 단계에서 에러가 발생하는지를 먼저 확인할 필요가 있었습니다. 위 로그를 가지고 알 수 있는 것은 ‘Uploading metadata to App Store Connect’ 단계에서 문제가 발생했다는 것과, ‘Unexpected Error’ 라는 것입니다. 메타데이터를 업로드하는 단계에서 발생한 예상치 못한 에러라니. 모호해도 너무 모호합니다. 더 많은 정보가 필요합니다.</p><p>빠른 피드백을 위해 로컬 머신에 에러를 재현할 수 있는 간단한 스크립트를 작성했습니다. 빌드나 스크린샷 업로드를 모두 제외하고 메타데이터만 올리는 fastlane 스크립트입니다.</p><pre>lane :metadata do<br>  upload_to_app_store(<br>    force: true,<br>    skip_binary_upload: true,<br>    skip_screenshots: true,<br>    app_version: &#39;3.55.0&#39;,<br>    build_number: &#39;934&#39;,<br>  )<br>end</pre><p>그리고 상세한 로그를 보기 위해 — verbose 옵션을 사용해서 실행했습니다.</p><pre>bundle exec fastlane metadata --verbose</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*b80w2IC8Hl_WSuw5Ix91_g.png" /></figure><p>이번에는 stack trace 정보까지 함께 출력됩니다. handle_itc_response() 함수에서 Spaceship::Tunes::PotentialServerError 에러가 발생한 것을 볼 수 있습니다. 앱스토어 커넥트 API에서 에러가 난 것임을 확인할 수 있습니다.</p><h3>검색</h3><p>fastlane는 스크립트가 실패하면 GitHub 이슈를 검색하도록 유도합니다. 자동으로 검색해주는 이슈들은 전혀 연관성이 없었고, 추가 링크를 통해서 한 개의 이슈(<a href="https://github.com/fastlane/fastlane/issues/14214">#14214</a>)를 확인할 수 있었습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gesldXEt45f0kYgx-_vLOQ.png" /></figure><p>이슈의 댓글을 모두 살펴봤습니다. 첫 번째 댓글은 로그를 확인해보라는 댓글이었습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YPfWSHE6ILA7HauPwqA4xQ.png" /></figure><p>로그를 보면 조금 더 상세한 정보가 있지 않을까 하는 기대를 가지고 열어보았지만, 앱스토어 커넥트 서버에서 Unexpected Error를 반환하는 것 외에는 더 많은 정보를 얻지 못했습니다. 이미 알고 있는 정보입니다.</p><pre>DEBUG [01:38:40]: &lt;&lt; POST ra/apps/458165974/platforms/ios/versions/836157375: 500 {&quot;data&quot;=&gt;nil, &quot;messages&quot;=&gt;{&quot;warn&quot;=&gt;nil, &quot;error&quot;=&gt;[&quot;Unexpected Error&quot;], &quot;info&quot;=&gt;nil}, &quot;statusCode&quot;=&gt;&quot;ERROR&quot;}<br>DEBUG [01:38:40]: Request was successful</pre><p>두 번째 댓글은 state와 country 관련 정보를 주석처리했더니 해결됐다는 내용이었습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LewOTUvtnVy1yRVRvh8lTw.png" /></figure><p>fastlane/metadata/trade_representative_contact_information 디렉토리의 country.txt와 state.txt 내용을 모두 제거해서 빈 파일로 만들어봤지만 여전히 문제가 재현됐습니다.</p><p>마지막 댓글은 스크립트를 수정해서 해결했다고 자랑하는(?) 글이었습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Lm6orBp1zQ6b46NZrLQgxA.png" /><figcaption>뭘 어떻게 수정했는지를 알려줘야지…</figcaption></figure><h3>추론</h3><p>정보 수집 과정에서는 뾰족한 해결책을 찾을 수 없었습니다. 따라서 생길 수 있을 법한 몇 가지 가설을 세웠습니다. Unexpected Error는 사실상 모든 경우를 포괄할 수 있기 때문에 최대한 많은 경우의 수를 생각하려 했습니다.</p><ol><li>앱스토어 커넥트 서버에 장애가 있을 것이다.</li><li>fastlane 버전에 문제가 있을 것이다.</li><li>빌드 머신에 문제가 있을 것이다.</li><li>프로젝트에 문제가 있을 것이다.</li><li>애플 계정에 문제가 있을 것이다.</li><li>메타데이터에 문제가 있을 것이다.</li></ol><p><strong>가설 1. 앱스토어 커넥트 서버에 장애가 있을 것이다.<br></strong>갑작스럽게 문제가 생겼고, 예상치 못한 에러라는 것을 봤을 때 서비스 장애가 원인일 수 있겠다는 생각을 했습니다. 이런 경우 <a href="https://developer.apple.com/system-status/">공식 Status 페이지</a>를 가장 먼저 참고하고, 두 번째로는 트위터에서 실시간 트윗을 검색합니다. Status 페이지에서도 문제가 없고, 트위터에서 #fastlane #appstore #outage 등의 키워드로 검색했을 때 실시간 검색 결과가 없는 것을 확인했습니다.<br>👉 탈락</p><p><strong>가설 2. fastlane 버전에 문제가 있을 것이다.<br></strong>기존에 사용하던 버전은 2.145.0입니다. 지난주 릴리즈에서 같은 버전을 사용했는데 문제가 없었습니다. 애플의 코드 변경에 종속적인 fastlane의 특성상 불안정한 경우가 많기 때문에, 혹시나 하는 마음으로 최신 버전인 2.148.1로 업그레이드 해보았지만 여전히 문제가 발생합니다.<br>👉 탈락</p><p><strong>가설 3. 빌드 머신에 문제가 있을 것이다.<br></strong>빌드 머신에서 크리덴셜을 잘못 꺼내오거나, 빌드 캐시를 복구할 때 일부 파일에 문제가 생겼을 가능성을 의심했습니다. 배포 파이프라인을 몇 번 재시도 하는 동안 여러 대의 빌드 머신에서 작동되었고, 모두 실패했습니다. 로컬 머신에서도 테스트해 보았으나 같은 문제가 발생합니다.<br>👉 탈락</p><p><strong>가설 4. 프로젝트 설정에 문제가 있을 것이다.<br></strong>여러 명의 개발자가 코드를 작성하기 때문에 미처 리뷰하지 못한 프로젝트 설정 변경이 있을 수 있습니다. 관련이 있을 법한 디렉토리의 커밋 히스토리를 모두 탐색했지만 변화가 없었습니다. 또한 개인 프로젝트에서 같은 스크립트를 실행했더니 동일한 문제로 실패했습니다.<br>👉 탈락</p><p><strong>가설 5. 애플 계정에 문제가 있을 것이다.<br></strong>정책 변경에 동의하지 않았거나 계정 권한을 잘못 설정하는 등의 문제를 생각했습니다. Account Holder 계정으로 앱스토어 커넥트와 애플 개발자 사이트에 접속해 보았으나 별다른 경고가 없었습니다. 권한도 그대로 가지고 있었습니다. 개인 프로젝트에서 개인 애플 계정을 사용해서 테스트해 보았으나 똑같은 문제가 발생했습니다.<br>👉 탈락</p><p><strong>가설 6. 메타데이터에 문제가 있을 것이다.<br></strong>불과 일주일 전 릴리즈만 해도 잘 됐고, 메타데이터 변경이 일절 없었기 때문에 가장 가능성이 낮습니다. 그리고 메타데이터에 문제가 있었다면 충분히 많은 검색 결과가 있었을 것입니다. 따라서 마지막 가설로 남겨뒀습니다. 하지만 셜록의 유명한 말처럼, 나머지 가능성을 모두 제거하고 남은 것은 사실일 가능성이 있어 검증할 필요가 있었습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/550/1*91iGYmQ8vdG1nZlDuOl6qw.jpeg" /></figure><h3>메타데이터에 문제가 있었을까?</h3><p>fastlane 메타데이터에는 여러 파일이 존재합니다. 정확히 어떤 메타데이터에서 문제가 생겼는지를 확인하기 위해 수동으로 이진 탐색했습니다. 파일들 중 절반을 다른 곳으로 옮겨두고 스크립트를 실행합니다. 만약 문제가 생긴다면 또 반을 나눠서 테스트하는 과정을 반복합니다. 문제가 생기지 않는다면 옮겨둔 다른 절반에서 같은 과정을 반복합니다.</p><p>O(log N)의 시간복잡도를 가진 이진 탐색의 효율성 덕분에 금방 문제의 파일을 발견할 수 있었습니다. fastlane/metadata/trade_representative_contact_information/country.txt 파일을 제거하니까 문제가 사라졌습니다. 분명 이슈를 검색해서 나온 댓글을 따라 내용을 모두 삭제했을 때에는 문제가 여전히 있었는데, 파일을 삭제하니까 문제가 해결됐습니다. 유효성 검사에서 실패한 것을 의심했습니다.</p><h3>해결하기</h3><p>country.txt의 기존 값은 Korea, Republic Of 였습니다. &#39;대한민국&#39;을 표현하는 값이 어떤 값으로 변경해야 하는지 확인할 필요가 있었습니다. 하지만 fastlane에서 사용하는 API는 비공식이기 때문에 별도의 문서가 존재하지 않습니다. fastlane으로 앱스토어 커넥트에 등록된 메타데이터를 직접 내려받으면 최신 값을 얻을 수 있을 것 같았습니다.</p><pre>bundle exec fastlane deliver download_metadata -m &quot;./itc-metadata&quot;</pre><p>그리고 나서 country.txt값을 확인해 보았더니 South Korea였습니다. 같은 값으로 수정하고 스크립트를 실행했더니 성공했습니다. 문제 해결!</p><h3>결론</h3><p>불과 저번주 수요일 저녁까지만 해도 문제 없이 릴리즈되었습니다. 따라서 최근에 앱스토어 커넥트에 변경이 있었을 것 같습니다. 하필이면 인터넷에 자료가 많지 않은 대한민국 표기 방식의 변화라 더욱 찾기 어려웠습니다. 혹시나 같은 현상으로 문제를 겪고 계신 다른 개발자분들께 도움이 되기를 바랍니다.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2c6fd0cd6577" width="1" height="1" alt=""><hr><p><a href="https://medium.com/styleshare/fastlane%EC%97%90%EC%84%9C-unexpected-error%EB%A1%9C-ios-%EC%95%B1%EC%9D%84-%EC%A0%9C%EC%B6%9C%ED%95%A0-%EC%88%98-%EC%97%86%EB%8A%94-%EB%AC%B8%EC%A0%9C-%ED%95%B4%EA%B2%B0%ED%95%98%EA%B8%B0-2c6fd0cd6577">fastlane에서 Unexpected Error로 iOS 앱을 제출할 수 없는 문제 해결하기</a> was originally published in <a href="https://medium.com/styleshare">StyleShare</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[상품상세페이지 개선해 성과내기]]></title>
            <link>https://medium.com/styleshare/%EC%83%81%ED%92%88%EC%83%81%EC%84%B8%ED%8E%98%EC%9D%B4%EC%A7%80-%EA%B0%9C%EC%84%A0%ED%95%B4-%EC%84%B1%EA%B3%BC%EB%82%B4%EA%B8%B0-ae9d5cf651c1?source=rss----ed9cf866ec01---4</link>
            <guid isPermaLink="false">https://medium.com/p/ae9d5cf651c1</guid>
            <category><![CDATA[ui-ux-design]]></category>
            <category><![CDATA[product-design]]></category>
            <category><![CDATA[commerce]]></category>
            <dc:creator><![CDATA[Summer Bom]]></dc:creator>
            <pubDate>Sun, 29 Dec 2019 14:49:39 GMT</pubDate>
            <atom:updated>2020-03-24T10:02:17.661Z</atom:updated>
            <content:encoded><![CDATA[<h3>상품상세페이지 개선해 성과내기</h3><p>지난 분기, 상품 상세 페이지를 개선했습니다. 스타일쉐어 서비스에서 가장 중요한 End Page중 하나입니다. 결국 End Page로 얼만큼 많이 유입시켰고, 비즈니스 효과를 냈는 지가 서비스의 지표, 볼륨이 됩니다. 그래도 트래픽이 적은 웹이라 부담감은 크지 않았습니다. 오히려 선행 과제로 AB테스트할 수있었습니다.</p><p>상품상세페이지 개선의 목표는 두 가지였습니다.</p><ul><li>유저가 상품상세에서 이탈하지 않고 다음 단계로 전환될 수 있게 돕는다</li><li>첫 구매자의 구매 전환률을 상승시킨다</li></ul><h3>일의 방법 정하기</h3><p>Goal을 받고는 문제를 정의하기 시작했습니다. 이 단계에서 PM과 가장 많은 이야기를 했어요. 갑론을박도 하고 데이터 찾아달라 떼써가며 <strong>문제라 생각했던 게 진짜 문제가 맞는 지</strong>의 과정을 거쳤습니다.</p><p>전 이 과정이 디자인보다도 중요하다고 생각합니다. 사실 꽤 피곤해요. 어쩌면 누구나 알 법하고, 처음이랑 똑같은 문제 정의가 나오기도 합니다. 하지만 이 과정에서 <strong>‘개선 과정에서 누구나 필요하다고 말하는 부분이 정말 필요한 지, 그렇다면 서비스의 차별화는 어떻게 녹여내 임팩트를 높일 것인지’</strong> 등 심도 있는 파악을 하게 됩니다. 그러면서 의욕과 자신감도 생겼구요.</p><p>그리고 상품 상세 페이지의 <strong>역할을 정의</strong>했습니다. 이 부분을 저는 <strong>컨셉</strong>이라고 부르는데, 그 컨셉대로 잘 굴러가는 지 결과를 파악하기 위해 목표 지표도 함께 설정합니다.</p><h3>너의 역할은</h3><h4>1. 종착역과 환승역</h4><p>웹에서 상품 상세 페이지는 유입되는 경로가 정말 많은 페이지입니다. 그 중 네이버 최저가 검색이 압도적이었습니다.</p><p>목적이 강한 페이지이기 때문에 추천과 관련된 콘텐츠를 자연스럽게 제공한다면 다른 페이지로 유입도 얼마든지 유입시킬 수있는 페이지입니다.</p><h4>2. 서비스의 첫 인상</h4><p>보통 <strong>홈</strong>이라고 부르는 화면을 서비스의 첫 화면이라고 합니다.</p><p>하지만 Web에서는 사람들은 스타일쉐어를 상품 상세 페이지로 처음 만납니다. 게다가 스타일쉐어를 모르는 사용자가 대부분입니다.</p><p>첫 인상에서 커머스 서비스가 마땅히 주어야 할 인상은 <strong>신뢰</strong>입니다. 신뢰를 주는 커머스에 대해 연구한 자료를 참고했습니다. ‘<strong>심미성</strong>’도 리스트에 포함되어 있었습니다.</p><ul><li>사회적 증거 적용: 실제 구매 숫자, 반응 숫자, 리뷰 개수 등…</li><li>디자인이 심플할 수록 신뢰성을 주는 연구가 있음</li><li>첫 구매 쿠폰 노출: 날 사다오! 같은 찌라시처럼 보이기 쉬운 페이지라 혜택 배너를 최대한 UI에 녹아들도록 디자인했습니다.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2vUDRyTYNV5ctoLzaRGlnA.png" /></figure><h3>디자인 조금 더 들여다보기</h3><h4>1. ATF영역</h4><p>상품 상세페이지에서 가장 중요한 영역입니다. 상품의 모든 정보가 다 담겨 있지만 첫 인상이죠.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ad3oCoBeIyotHQIZTt_jqA.png" /></figure><ul><li><strong>가격 경쟁력</strong>: 이 페이지로 가장 많이 유입되는 경로는 네이버 최저가 검색이었습니다. 가격에 예민한 유저를 고려해 쿠폰 혜택 가격을 노출하고 <strong>최저가 하나만 강조</strong>했습니다.</li><li><strong>상품명 단순화</strong>: 대괄호는 디자이너입장에서 정말 난감합니다.. 가독성도 안좋고 정보 분리도 되어 있지 않아 너무 없애고 싶은 존재.. 하지만 판매자나 공급자는 잘 팔고 싶고. 그래서 팀에서 상품명에 사용된 대괄호를 몇 가지 패턴으로 추려내고 <strong>총 6가지로 대치, 통합</strong>을 했습니다. 사용자에게는 3개만 노출됩니다.</li><li><strong>사회적 증거</strong>: 스타일쉐어에서만 줄 수있는 숫자입니다. 다른 사람도 이용하고 있다는 직접적인 숫자입니다.</li><li><strong>GNB 영역</strong>: 흰 배경에 텍스트는 탭 메뉴 내용이 강조되어 보여 복잡도를 야기했습니다.</li></ul><h4>2. 상품 PV 늘리기</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Ms7-AfptPqo-G2zsVTmwPA.png" /></figure><ul><li><strong>소 카테고리 추천 상품</strong>: 가장 연관성이 높은 상품군인 소 카테고리를 추천합니다.</li><li><strong>브랜드 인기 상품</strong>: 특히 브랜드 페이지 내에서 상품 PV가 매우 높았기 때문에 사용자의 니즈로 파악해 UI에서 중복 노출 및 큰 지분을 주었습니다.</li></ul><h4>3. CTA Button</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*U8Knd3HbIqdQZOQbGrnckw.png" /></figure><p>우리나라 커머스에서는 ‘바로구매’를 더 강조하고 있습니다. 서양 커머스에서는 ‘장바구니’죠. 궁금했어요. 더 좋은 사용성과 더 높은 비즈니스 임팩트는 뭔지 실험을 해 보고 싶었습니다.</p><p>다음 컨버전을 늘리기 위해 과감히 ‘장바구니 담기’로 CTA 버튼을 변경했습니다(PM이 밀어붙였고 저는 망설였지만 실험이니까 일단 Go).</p><h3>그래서 결과는?</h3><p>AB테스트를 했고, <strong>목표했던 지표 상승</strong>을 이루었습니다.</p><h4>1. 장바구니 → 주문서 → 구매 완료 컨버전</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9FgO03Ocaj-1bobwwW9D6w.png" /><figcaption>상품상세페이지 방문을 100%로 보고 그 후의 퍼널 %</figcaption></figure><p>전체 퍼널에서 실험군 결과가 모두 좋았습니다. <strong>구매 완료까지 약 20% 성장</strong>이 있었어요. 짝짝.</p><p>CTA버튼을 장바구니로 전환시킨 결정이 큰 영향을 미친 걸 알 수있었습니다. 장바구니에 담기만 하고 페이지에 방문하지 않을까봐 걱정했는데, 기우였습니다.</p><h4>2. 로그인/가입 하는 유저의 비율</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HUxGyq1cPKjtBNtwF4quKA.png" /><figcaption>상품상세페이지 방문을 100%</figcaption></figure><p>서비스의 좋은 첫 인상이라는 역할을 잘 수행했는 지 보려면 서비스에 로그인/가입 하려는 시도를 보면 좋겠다고 생각했었습니다.</p><ul><li>로그인/가입 페이지까지: 기존 페이지는 17%, 실험군은 45%의 유저가 로그인 및 가입을 시도했습니다.</li><li>로그인/가입 완료: 기존 11%, 실험군: 32%</li></ul><h4>3. 브랜드 페이지 유입률</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Bkny3qKoVHffr68jtONUcw.png" /><figcaption>상품상세페이지 방문을 100%로</figcaption></figure><p>브랜드 페이지에서 상품상세페이지 PV가 높기 때문에 전체적으로 상품상세페이지 PV도 함께 증가하는 선순환을 가져왔습니다.</p><h4>4. 가장 고무적인 건 리텐션률. 제품은 장기적으로.</h4><p>실험군이 <strong>약 4배 정도 높았습니다.</strong></p><p>처음 개선 프로젝트 미션을 받았을 때 리텐션은 목표 지표에 없었습니다. 하지만 모든 개선이라는 미션의 목표는 밑 빠진 독의 구멍을 최소화하는 것입니다. 제품이 좋으면 마케팅 비용도 절감되기에 더 큰 효과를 냅니다.</p><blockquote><em>새로운 고객을 확보하는 것은 기존 고객을 확보하는 것보다 5 ~ 25 배 더 비쌉니다. 이는 고객 유지율을 5 % 증가 시키면 이익을 25–95 % 사이에서 증가시킬 수 있으므로 ROI의 실천이 아니라 실제로 더 많은 돈을 벌 수 있음을 보여줍니다. [</em><a href="https://www.salesforce.com/products/service-cloud/best-practices/customer-retention-rate/#)"><em>출처</em></a><em>]</em></blockquote><h3>프로젝트 회고</h3><p>중요한 페이지이지만 웹의 트래픽이 적어 <strong>이것저것 실험</strong>할 수있던 좋은 기회였습니다. 커머스 서비스에서 가장 중요한 정보가 많은 페이지를 뜯어보면서 얽히고 얽힌 이해관계자의 니즈를 체감할 수있었습니다. 가령 상품명이 저렇게 된 이유, 네이버 최저가 검색이 역시 짱이다, 같은 것들.</p><p>처음 서비스를 찾는 건 프로모션이든 입소문이든 마케팅일 수밖에 없지만, 다시 돌아오게 하는 건 프로덕트의 역할이라고 생각합니다. 막중하죠. (나 혼자 진지해?)</p><p>누구나 하는 말이지만, 작은 실험에서 성과가 났다고 해서 그 디자인이 끝이 아닙니다. 실험한 이유는 다음에 잘하기 위해서니까요! 아마 그 다음도 실험이 되겠지만, 계속해서 얻고 반영해보고 또 얻고 하는 게 제 일의 매력이 아닐까 하는 (간절한) 생각을 해봅니다.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ae9d5cf651c1" width="1" height="1" alt=""><hr><p><a href="https://medium.com/styleshare/%EC%83%81%ED%92%88%EC%83%81%EC%84%B8%ED%8E%98%EC%9D%B4%EC%A7%80-%EA%B0%9C%EC%84%A0%ED%95%B4-%EC%84%B1%EA%B3%BC%EB%82%B4%EA%B8%B0-ae9d5cf651c1">상품상세페이지 개선해 성과내기</a> was originally published in <a href="https://medium.com/styleshare">StyleShare</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[iOS 13 에서 변경된 UIModalPresentationStyle 해킹하기]]></title>
            <link>https://medium.com/styleshare/ios-13-%EC%97%90%EC%84%9C-%EB%B3%80%EA%B2%BD%EB%90%9C-uimodalpresentationstyle-%ED%95%B4%ED%82%B9%ED%95%98%EA%B8%B0-3b18279a1a2c?source=rss----ed9cf866ec01---4</link>
            <guid isPermaLink="false">https://medium.com/p/3b18279a1a2c</guid>
            <category><![CDATA[uimodalpresentationstyle]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[swif]]></category>
            <category><![CDATA[ios-13]]></category>
            <category><![CDATA[develop]]></category>
            <dc:creator><![CDATA[전수열]]></dc:creator>
            <pubDate>Fri, 27 Sep 2019 06:37:06 GMT</pubDate>
            <atom:updated>2020-10-19T08:57:13.411Z</atom:updated>
            <content:encoded><![CDATA[<p>iOS 13에는 많은 변화가 있었습니다. 그 중 가장 개발자들을 당황스럽게 만든 변화는 UIViewController.modalPresentationStyle의 기본 값이 변경된 것입니다. 기존에는 present(_:animated:completion:) 메서드를 사용하면 뷰 컨트롤러가 전체 화면으로 표시되었습니다. 하지만 iOS 13부터는 모달 형태로 표시되면서 기존에 작성한 많은 인터페이스가 망가지게 됩니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*iv6tDqwY9nIDGq9FGb2qtw.png" /><figcaption>모두를 당황시킨 iOS 13 (오른쪽이 정상)</figcaption></figure><p>이를 바로잡기 위해서는 UIViewController.modalPresentationStyle 속성을 기본값인 .automatic 이 아니라 .fullScreen 으로 변경해주어야 합니다. 네비게이션 컨트롤러 없이 뷰 컨트롤러를 표시하는 경우에는 프로젝트에서 사용하는 BaseViewController의 기본 속성을 바꿔주는 간단한 방법이 있습니다. 하지만 네비게이션 컨트롤러를 사용해서 뷰 컨트롤러를 띄우는 경우에는 모든 코드에 아래와 같은 변경을 추가해주어야 합니다.</p><pre>let navigationController = UINavigationController(...)<br>navigationController.modalPresentationStyle = .fullScreen<br>self.present(navigationController, animated: true, completion: nil)</pre><p>모든 코드를 찾기 어려울 뿐더러, 분명히 미래에 실수할 여지가 있습니다. 따라서 한 번에 모든 곳의 기본값을 변경할 수 있는 방법이 필요합니다. StyleShare에서는 이에 대응하기 위해 세 가지 방법을 고민해보았습니다.</p><h3>1. Method Swizzling</h3><p>UINavigationController 런타임을 조작하여 modalPresentationStyle의 값을 .fullScreen으로 바꿔치기 하는 방법입니다. 잘만 사용하면 굉장히 유용하지만 클래스의 기본 구현을 바꿔버리기 때문에 상당히 위험한 기술입니다. 의도하지 않게 시스템 프레임워크나 서드파티 프레임워크의 구현을 망가뜨릴 수 있어 채택하지 않았습니다.</p><h3>2. 커스텀 UINavigationController 작성</h3><p>modalPresentationStyle 기본 값을 .fullScreen 으로 설정한 MyFullScreenNavigationController를 작성하는 방법입니다. UINavigationController를 사용하는 곳을 모두 이 클래스로 치환해야 합니다. 가장 정직한 방법이지만, 너무나 많은 코드 변경이 생기게 됩니다. 또한 미래에 이 클래스를 사용하지 않고 UINavigationController를 직접 사용하게 되는 실수가 생길 수 있어 채택하지 않았습니다.</p><h3>3. 스코프(Scope) 우선순위 해킹하기</h3><p>Swift는 다른 언어와 마찬가지로 스코프 우선 순위가 있습니다. 가장 개발자의 의도와 가까운 곳부터 먼 순서대로 우선 순위가 정해집니다. 대표적인 예시는 아래와 같습니다. 같은 이름을 가진 변수를 전역 스코프, 클래스 멤버 스코프, 그리고 로컬 스코프에 정의하면 참조하는 곳과 가장 가까운 로컬 변수가 가장 높은 우선 순위를 가집니다.</p><pre>let foo: String = &quot;A&quot;</pre><pre>class Hello {<br>  let foo: String = &quot;B&quot;</pre><pre>  func world() {<br>    let foo: String = &quot;C&quot;<br>    print(foo) // &quot;C&quot;<br>  }<br>}</pre><p>변수 뿐만 아니라 타입을 정의할 때도 마찬가지입니다.</p><pre>import struct ThirdParty.User</pre><pre>struct User {<br>  let name = &quot;B&quot;</pre><pre>  func hello() {<br>    struct User {<br>      let name = &quot;C&quot;<br>    }</pre><pre>    let user = User()<br>    print(user.name) // &quot;C&quot;<br>  }<br>}</pre><p>이를 이용해서 UINavigationController의 네임스페이스 우선순위를 해킹할 수 있습니다. 기존의 UINavigationController들은 임포트한 UIKit 네임스페이스를 가집니다. 타입 이름이 같다면 같은 모듈의 클래스가 더 높은 스코프 우선순위를 가지게 됩니다. 즉, 프로젝트에 또다른 UINavigationController를 정의하면 모든 UINavigationController에 대한 참조가 UIKit.UINavigationController 에서 MyApp.UINavigationController로 바뀌게 됩니다.</p><pre>import UIKit</pre><pre>class UINavigationController: UIKit.UINavigationController {<br>}</pre><pre>let navigationController: UINavigationController // MyApp.UINavigationController</pre><p>그리고 이 클래스 생성자에서 modalPresentationStyle의 값을 .fullScreen으로 바꿔주기만 하면 됩니다.</p><p>UINavigationController라고만 네이밍하면 의도가 드러나지 않을 수 있습니다. StyleShare에서는 의도를 명확히 드러내는 것을 중요하게 생각합니다. 따라서 _FullScreenModalNavigationController로 이름짓고, typealias를 사용해서 UINavigationController 네임스페이스를 덮어씌웠습니다. 아래는 최종 구현입니다.</p><pre>import UIKit</pre><pre>typealias UINavigationController = _FullScreenModalNavigationController</pre><pre>class _FullScreenModalNavigationController: UIKit.UINavigationController {<br>  override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {<br>    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)<br>    self.modalPresentationStyle = .fullScreen<br>  }</pre><pre>  override init(rootViewController: UIViewController) {<br>    super.init(rootViewController: rootViewController)<br>    self.modalPresentationStyle = .fullScreen<br>  }</pre><pre>  convenience init() {<br>    self.init(nibName: nil, bundle: nil)<br>  }</pre><pre>  required init?(coder: NSCoder) {<br>    super.init(coder: coder)<br>    self.modalPresentationStyle = .fullScreen<br>  }<br>}</pre><p>만약 UIKit의 UINavigationController를 사용할 필요가 있다면 네임스페이스를 명시해서 UIKit.UINavigationController 처럼 사용하면 됩니다.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3b18279a1a2c" width="1" height="1" alt=""><hr><p><a href="https://medium.com/styleshare/ios-13-%EC%97%90%EC%84%9C-%EB%B3%80%EA%B2%BD%EB%90%9C-uimodalpresentationstyle-%ED%95%B4%ED%82%B9%ED%95%98%EA%B8%B0-3b18279a1a2c">iOS 13 에서 변경된 UIModalPresentationStyle 해킹하기</a> was originally published in <a href="https://medium.com/styleshare">StyleShare</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[스타일쉐어의 일곱번 째 오피스, 선릉]]></title>
            <link>https://medium.com/styleshare/%EC%A0%80-%ED%91%B8%EB%A5%B8-%EC%84%A0%EB%A6%89-%EC%9C%84%EC%97%90-%EA%B7%B8%EB%A6%BC-%EA%B0%99%EC%9D%80-%EC%A7%91%EC%9D%84-%EC%A7%93%EA%B3%A0-6802cc2c66f2?source=rss----ed9cf866ec01---4</link>
            <guid isPermaLink="false">https://medium.com/p/6802cc2c66f2</guid>
            <category><![CDATA[office]]></category>
            <category><![CDATA[recruiting]]></category>
            <category><![CDATA[styleshare]]></category>
            <dc:creator><![CDATA[정새롬]]></dc:creator>
            <pubDate>Mon, 22 Apr 2019 12:02:46 GMT</pubDate>
            <atom:updated>2019-04-23T04:38:35.389Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*K_o-lYBne241rbTs1yPsGQ.jpeg" /></figure><p>오늘 2019년 4월 22일, 스타일쉐어가 일곱 번 째 집, ‘선릉’에서의 첫 하루를 보냈습니다.</p><p>2011년 연대 지하 차고에서 시작한 스타일쉐어는, 이제 92명의 팀원이 함께하는 결코 작지 않은 팀이 되었어요.</p><p>게다가 이번 선릉 오피스는 작년 3월 한 식구가 된 29CM과의 첫 물리적 결합이 이루어지는 장소입니다. 그렇기에 이번 이사에 대한 팀원들 모두의 설렘과 기대감이 아주 컸어요. (29CM은 6월 1일 입주)</p><p>처음 장소를 보고 그간 사무실 이전의 역사를 꿰고<em> </em>있던 오랜 팀원과, 그 옆의 입사한 지 한 달이 조금 넘은 제가 같은 말을 꺼냈습니다.</p><p>“와우, 스쉐 출세했다.”</p><p>분명 선릉 오피스는 그런 소리가 절로 나올 정도로 크고, 화려하고, 아름다운 사무실입니다.</p><p>인테리어도 연예인 신다은 씨와 함께 동상이몽에 출연하는 &lt;빌트바이&gt;의 임성빈 소장님이 맡아 주셨다고 해요. 정말 ‘스타일쉐어 많이 성장했다’고 뿌듯해할 수 있을 만큼의 투자가 들어간 셈이죠.</p><p>그런데 자세히 들여다보니, 결국 이전의 공간들과 다르지 않더라고요. 이곳이 우리의 <strong>공유</strong>와 <strong>협업</strong>의 문화 그리고 <strong>기억</strong>을 담는 그릇이 되기 위해 지어졌다는 점에서는요.</p><h3><strong>#공유</strong></h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VWU2-1pi7-n0oRoFP32k6A.jpeg" /><figcaption>네 개 층을 씁니다. 3·4층은 스타일쉐어와 29CM이 각각 쓰는 오피스로, 1·2층은 양사가 함께 하는 공간으로 활용됩니다.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BZiIrT1LPRpUe5qmHFmnlg.jpeg" /><figcaption>2층 커뮤니티 라운지는 스쉐와 29CM, 그리고 팀과 외부가 교류할 수 있는 공간입니다. 사무실 놀러오시면 여기로 모셔요!</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kMPDZu38iXOEN8Ia_HVkwA.jpeg" /><figcaption>북유럽 무드(?)의 소파와 테이블이 마련되어 있습니다. 이사 첫날부터 많은 팀원들이 회의+대화 공간을 활용하고 있어요. 다다음 달 29CM 팀이 입주하면, 이 공간에서 어떤 아이디어들이 오가게 될 지 기대가 됩니다.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pWLqAhnfOKi8t570sxd7Dg.jpeg" /><figcaption>라운지 뒷편에는 스벅같은 개인 업무 공간이 있어요. 따로 또 같이의 미학. 업무 효율도 200% 상승 장담합니다.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*S8p64uDrPYOKwMYwfYLriQ.jpeg" /><figcaption>졸린 고양이들처럼 해 받으면서 이야기 나누고 싶을 때 있지 않나요? 동료 간 편안하고 다정한 대화를 나눌 수 있는 공간입니다. (까사미아 표지인줄)</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*C9dCBN-mBWoU3iS7efq8Qw.jpeg" /><figcaption>우리 팀은 계약 관계로도 묶여있지만, ‘단이와 추의 공동 집사’라는 피보다 진한 연대로 묶여있습니다. 어김없이 단추의 방이 마련되었습니다. 이번에는 특별히 천장 놀이 공간과 자동 응가 거름 화장실(고가)도 선물 받았어요.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bzehujpbkeYcLviWpqmgZA.jpeg" /><figcaption>텃밭이 생겼어요! (우리는 모두 씨티파머!) 여름 되면 방울 토마토나 상추를 함께 길러서 잡아 먹을 수 있겠습니다.</figcaption></figure><h3>#협업</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lKu_yJhP9cQHTftRoUYmDQ.jpeg" /><figcaption>2,3 층 통틀어 총 14개의 크고 작은 미팅룸이 마련되어 있어요.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-9HkX94gzF3_JQyqKiRg7g.jpeg" /><figcaption>음식도 먹고, 둘러 앉아 업무 이야기도 나눌 수 있는 3층 캔틴 공간입니다.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AS6VPKE0TLkW-bLMzevJ9g.jpeg" /><figcaption>해가 갈수록 몸과 정신이 타협하고 협업해야 하는 일들이 많아집니다. 피로를 어르고 달랠 수 있는 6인 수면실입니다.</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YlF9JjHi3ZbWXuGO-o_W-g.jpeg" /><figcaption>스쉐 역사 상 처음으로 출산하는 팀원이 생겼어요. 기쁨과 축하의 마음을 담아 조용한 곳에 수유실을 마련했습니다.</figcaption></figure><h3>#기억</h3><p>회의실에는 과거 사무실 이름을 붙였습니다. <br>스쉐의 역사를 기억하고 기념하자는 의미에서입니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DyesAOGNpq6EJ3Ejjd64aQ.jpeg" /><figcaption>2011. 01 연대 지하 주차장, 스타일쉐어 시작. (2010~2011)</figcaption></figure><p><strong>연세차고<br>이곳에서 우리는,</strong></p><ul><li>제 10회 대한민국 대학생 벤처 창업 경진대회 TOP 10 입상 (2010.09)</li><li>연세 CEO 발굴 경진대회 대상 (2010.10)</li><li><strong>스타일쉐어 법인 설립</strong> (2011.06)</li><li>스타일쉐어 아이폰 앱 런칭 (2011.09)</li><li>애플 아이튠즈 앱스토어 추천앱 선정(2011.10)</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IBF81kEAdcfmdVk3_jdAYg.jpeg" /><figcaption>단이와 추를 입양한 방배 원룸 오피스텔, 제대로 된 첫 사무실이었던 압구정. (2013~2014)</figcaption></figure><p><strong>방배원룸과 압구정 <br>이곳에서 우리는,</strong></p><ul><li>스타일쉐어 1회 플리마켓 개최, 방문객 1만 명 (2013. 04)</li><li>네이버-스타일쉐어 패션 콘텐츠 제휴 (2013.09)</li><li>스타일쉐어 버전 2.0 런칭 (2014.04)</li><li><strong>시리즈 A 투자 유치</strong> (2014.05)</li><li><strong>회원수 100만 명 돌파</strong> (2014.10)</li><li>스타일쉐어 광고 시스템 런칭 (2014.12)</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YaV88Qb1hsSRbBKhUO7WgQ.jpeg" /><figcaption>팀원이 20명에서 40명으로 불어난 청담동 사무실, 팀원이 40명에서 90명으로 불어난 도산공원 사무실 (2015~2019.04.19)</figcaption></figure><p><strong>청담과 도산<br>이곳에서 우리는,</strong></p><ul><li>세계적 패션 에디터 수지 멘키스 사무실 방문 (2015.07)</li><li>스토어 결제 기능 도입 (2015.11)</li><li><strong>스타일쉐어 버전 3.0 런칭- 커머스 기능</strong> (2016.04)</li><li>1년 만에 스토어 누적 거래액 100억 돌파 (2017.04)</li><li>스타일쉐어 앱 400만 다운로드 돌파 (2017.08)</li><li>스토어 누적 거래액 300억 돌파 (2017.12)</li><li><strong>온라인 편집숍 29CM 인수 </strong>(2018.03)</li><li>월 MAU 100만 달성(2018.09)</li><li>스타일쉐어 X 29CM ‘2018 슈퍼마켓페스트’ 4만 명 방문(2018.10)</li><li><strong>스타일쉐어 + 29CM 연간 거래액 1,200억 돌파 </strong>(2018.12)</li><li>편의점 현금 결제 서비스 출시 (2019.01)</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_4BhgraWYEm-V2gcSxH5zA.jpeg" /><figcaption>29CM의 역사를 담은 이화, 동숭, 양화 사무실. (2011~2019.05)</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WI0WqxoyDQrCTHuEshAliw.jpeg" /><figcaption>스타일쉐어와 29CM이 하나가 된 선릉 사무실. (2019.04~)</figcaption></figure><p><strong>그리고 선릉.</strong> <br><strong>이곳에서 우리는,</strong></p><p>무엇을 만들어 갈 수 있을까요?<br>내일을, 그리고 내년을 기대하는 마음으로 <br>새 사무실에서의 하루를 마감합니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wNUg8EZc8gIBGObA41zqFw.jpeg" /></figure><ul><li><strong>별책부록 <br></strong>스타일쉐어 팀원들이 수년에 걸쳐 완성한 <a href="https://www.google.com/maps/d/u/0/edit?mid=1c_mIwvK4F_dAZH4kwIeY8F6NCwaYSL6A&amp;ll=37.52308633019658%2C127.03394750000007&amp;z=17">도산공원 맛집 대장</a></li></ul><p>+ 예상치 못한 새집 증후군</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tzDDvWZhrp8qA-rMGZecTQ@2x.jpeg" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6802cc2c66f2" width="1" height="1" alt=""><hr><p><a href="https://medium.com/styleshare/%EC%A0%80-%ED%91%B8%EB%A5%B8-%EC%84%A0%EB%A6%89-%EC%9C%84%EC%97%90-%EA%B7%B8%EB%A6%BC-%EA%B0%99%EC%9D%80-%EC%A7%91%EC%9D%84-%EC%A7%93%EA%B3%A0-6802cc2c66f2">스타일쉐어의 일곱번 째 오피스, 선릉</a> was originally published in <a href="https://medium.com/styleshare">StyleShare</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[UX DAYS Seoul 2019(1/2)]]></title>
            <link>https://medium.com/styleshare/ux-days-seoul-2019-1-2-3ebedae3136b?source=rss----ed9cf866ec01---4</link>
            <guid isPermaLink="false">https://medium.com/p/3ebedae3136b</guid>
            <category><![CDATA[ux-day]]></category>
            <category><![CDATA[service-design]]></category>
            <category><![CDATA[onboarding]]></category>
            <category><![CDATA[ux]]></category>
            <category><![CDATA[voice-ui]]></category>
            <dc:creator><![CDATA[Summer Bom]]></dc:creator>
            <pubDate>Tue, 16 Apr 2019 02:20:39 GMT</pubDate>
            <atom:updated>2019-04-16T02:34:21.473Z</atom:updated>
            <content:encoded><![CDATA[<p><strong>구글·아마존 대표 UX 디자이너들이 말하는 성공의 비결</strong></p><h3>시작하며</h3><p>얼마 전, 스타일쉐어 디자인팀은 만나기 힘든 해외 연사를 만날 수있는 좋은 기회인 UX DAYS Seoul에 다녀왔습니다. 일본에서는 벌써 5번 진행했는데 서울에서는 올해 처음이었습니다. 앞으로 워크샵으로도 종종 찾아뵐 예정이라고 합니다.</p><p>컨퍼런스는 4월 3일 하루종일 진행되었습니다. “UX는 디지털 비즈니스의 성공 열쇠”라는 부제목에서 느낄 수 있듯, UX라는 주제 안에서 개괄적인 내용부터 비즈니스에서 어떤 역할을 하는 지까지, 다양한 이야기가 오갔습니다.</p><p>사용자 온보딩, 리서치처럼 세부적인 주제도 있었고 서비스 디자인, 음성 인터페이스같은 큰 범주 내용도 있었습니다. 스타트업에서 일하면서 느끼는 건, 바로 업무를 하는 실무자가 장기 계획과 비즈니스 맥락도 반영하면서 일을 진행해야 한다는 것입니다. 적은 인원으로 빠르게 성장하려면, 개인이 가진 소스가 큰 영향력을 갖기 때문입니다.</p><p>UX DAYS에서는 국내에서 찾기 어려운 실제 레퍼런스와 사전 연구가 많이 소개되었습니다. 컨퍼런스에서 총 6개의 세션을 만날 수있었습니다. 내용이 길어 3개씩 나누어 소개하려 합니다.</p><ol><li>구글 수석 UX 디자이너가 말하는 ‘장기적 사용자 온보딩’ (1/2)</li><li>아마존 UX 대표 디자이너의 ‘음성 디자인에 힘을 전달하는 방법’ (1/2)</li><li>서비스 디자인으로 즐거움과 규모를 확장시키는 법 (1/2)</li><li>리서치를 위한 첫 질문은 무엇이 되어야 하는가? (2/2)</li><li>대형 컨설팅 회사가 행동 경제학자를 초빙하는 이유 (2/2)</li><li>비즈니스-UX 연결의 여왕이 말하는 ‘숫자 속 이야기 찾기’ (2/2)</li></ol><h3><strong>[장기적 사용자 온보딩]</strong></h3><p>Krystal Higgins — 구글 수석 UX 디자이너</p><blockquote><strong>Let’s design onboarding.</strong></blockquote><p>온보딩으로 고객의 여정에 다양한 이벤트로 설계할 수있습니다. 보통 우리가 얘기하는 온보딩은 한 부분만 이야기를 합니다.<br>사용자를 서비스와 친숙하게 만드는 것입니다.<strong> 하지만 온보딩은 다른 역할도 합니다.</strong></p><p>바로 사용자<strong>에 대해 배우는 것</strong>입니다. 온보딩으로 사용자의 니즈에 맞는 경험을 하도록 도와줄 수있습니다.<br>회원 가입, 유료 전환 등 비즈니스에 직접적으로 영향을 주도록 유도할 수도 있습니다.</p><p>온보딩을 최초 경험에만 국한한다면 다양한 역할을 할 수 없겠지만<strong> 장기적인 방법</strong>으로 접근한다면 다양한 환경을 계획할 수있습니다.</p><p>우리는 온보딩을 <strong>월 단위로 프로그램을 계획</strong>합니다.<strong> 6~12개월.</strong><br>온보딩이 제대로된 역할을 하려면 최소 첫째 날 이후까지 설계가 되어야 합니다. 사람들은 앱 사용 후 3~7일 내에 앞으로 계속 사용할 것인지 결정한다는 연구 결과가 있기 때문입니다.</p><h3>온보딩 기회</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0DjDVTB8odTKherXxAowyA.jpeg" /></figure><h4>A. 기초 온보딩 (Initial Onboarding)</h4><ol><li><strong>Lumosity: 두뇌 트레이닝 서비스</strong></li></ol><ul><li>각 게임이 어떤 트레이닝을 하는 지 안내 →방법 안내 →완료 후 정리 설명.</li><li>사용자의 현재 점수를 파악한다. 서비스가 어떻게 사용자에게 도움을 줄 지 파악할 수있다. → 유료 회원 가입</li><li>처음 사용 후 유료회원을 하는 것은 아니다. 그때 온보딩이 다시 작용.</li><li>그 후에 이메일로 스코어를 전송하면서 무료 트레이닝 프로그램을 제안한다. 더 나은 점수를 가질 수있고, 개발할 수있다고 안내.</li><li>회원 가입 후 다시 온보딩: 다음 단계로 계속 안내한다.</li><li>반복하는 방법: 게임을 하기 전/후, 대시 보드에서 스킬에 대한 안내를 제공하고 있음</li></ul><p><strong>2. IFTTT</strong></p><ul><li>익숙하게 하기(Familiarize): 신규 사용자가 바로 가입을 하도록 하지 않고, 시간을 주고 프로그램에 친숙해지도록 안내</li><li>전환하기(Convert): 마음에 드는 라이브러리가 있고 가지고 싶다면 가입을 하도록 안내</li><li>안내하기(Guide): 더 추가적인 애플릿 소개. 다음 단계로 사용자를 안내</li><li>교육하기(Learn): 정보를 기반으로 생성에 대한 안내</li></ul><h4>B. 연속적인 발견 (Continued Discovery)</h4><ol><li><strong>Etsy</strong><br>최근 새로운 ‘Pattern’ 서비스를 선보였습니다. 판매자들이 자신의 맞춤형 샵을 만드는 기능입니다.<br>배너를 통한 참여→대시보드→테마, 개인적으로 설정하는 옵션 등→무료</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IqtSdqx7xe32rOp3WuAhow.jpeg" /></figure><h4>C. 중요한 리디자인 (Major redesign)</h4><p>핵심적인 내용이 달라지기도 합니다.</p><ol><li><strong>구글 드라이브(Google Drive)</strong><br>서비스에 큰 변화가 있을 예정이었고, 어떻게 변경될 것인지 기존 사용자에게 계속해서 안내했습니다.<br>그 사이에 피드백을 받아서 모두가 만족할 수있는 결과를 만드는 과정을 보여주었습니다.</li></ol><h4>D. 잊고 있다가 다시 사용 (Return from lapse)</h4><p>사용자가 한동안 사용하지 않다가 돌아오는 경우</p><ol><li><strong>Turbortax</strong><br>세금관련 서비스입니다. 보통 이런 서비스는 1년동안 사용하지 않다가 다시 사용하는 패턴이 있습니다. 오랜만에 온 회원에게 그 사이에 어떻게 변경되었는 지 안내하는 온보딩을 할 수있습니다.</li></ol><h4>*망각 곡선 (Reinforce)</h4><p>온보딩을 하더라도 사용자는 필연적으로 서비스를 ㄹ잊습니다. 망각 곡선때문이죠. 하지만 이 망각 곡선을 개선할 수있는 방법이 있습니다. 교육계에서 많은 연구가 있습니다.<br>→ 반복적인 노출<br>→ 주요 기능을 계속 노출</p><h3>2. 다양한 방법</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ezBN-xJkwKFwBxQasfwSBw.jpeg" /></figure><p>고객들이 온보딩을 이용할 때 동일한 경로만 사용하지 않기 때문에 다양한 툴이 필요합니다. 고객 난이도에 따라 과정을 빠르거나 느리게 사용할 수도 있습니다.</p><blockquote>“반복적이고, 다양한 방법으로 접했을 때 이해도 더 빠르다”</blockquote><p><strong>완벽한 하나의 플로우를 만드는 대신 다양한 툴 킷을 만드는 것이 좋습니다.</strong></p><h4>디폴트 (Defaults)</h4><p><strong>기본 경험이 가장 중요합니다.</strong><br>프로덕트의 가장 초기 상태와 처음 접하는 사용자에게 어떻게 커뮤니케이션 되는 지 보여줍니다.</p><ul><li>콘텐츠 중심 서비스: 콘텐츠 아키텍쳐가 가장 중요합니다.</li><li>업무 중심 서비스: 공감하는 디자인이 중요합니다. 사용자가 질문을 하는 것으로 시작하면 좋습니다. (챗봇)</li></ul><h4>인라인 안내 (Inline guidance)</h4><p>여러 콘텐츠로 둘러쌓여있는 내부 일련의 경험</p><ol><li><strong>인스타그램 (Instagram)</strong><br>스토리 첫 번째에서 똑똑하게 새로운 기능을 안내합니다. 사용자가 매일 사용하는 콘텐츠 안에 들어가 있습니다.</li></ol><h4>반응 안내 (Reactive guidance)</h4><p>행동을 통한 학습 개념</p><ol><li><strong>구글 드라이브(Google Drive)</strong><br>파일을 서비스에 끌어오면 업로드할 수있다는 인터랙션을 줌으로써 즉각적으로 행동에 대한 결과를 안내해 줍니다.</li></ol><h4>예측 안내 (Proactive guidance)</h4><p>사용자 행동에 반응을 하기보다 예측하는 것입니다.</p><ol><li><strong>듀오링고 (Duolingo)</strong><br>빈 화면(Empty space)에서 행동을 유도</li><li><strong>에버노트 (Evernote)</strong><br>툴에 대한 힌트를 툴팁(Tooltip)으로 안내합니다.<br>이메일, 공지가 한 형태가 될 수있음: 실제로 제품에 알림 등을 제공</li></ol><h4>온디맨드 안내 (On-demand guidance)</h4><p>다양한 방법으로 온보딩을 해도, 분명히 빠진 부분이 생기게 됩니다.<br>그래서 <strong>도움말(Help contents)</strong>이 잘 구성되어야 합니다. 사용자가 질문이 있을 때 쉽게 찾을 수있도록 설계하는 게 중요합니다.</p><h3>정리</h3><p>온보딩을 단기적인 방법으로 평가를 하려고 하는 경우가 많습니다.<br>예를 들면 5초의 첫 인상, 프로덕트 기능에 대해 이해를 했는 지, 가입이 얼마나 완료됐는 지 등등… 하지만 이런 <strong>단기적인 방식으로는 온보딩을 평가할 수없습니다.<br></strong>장기적으로 신규 사용자의 경험을 개선하기가 어렵습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tf3G2zv8JoqpPWetb-RrLQ.jpeg" /><figcaption>HR의 온보딩 과정</figcaption></figure><p>HR에서는 신입사원이 온보딩을 경험하고 평가하는 과정이 있습니다. <strong>입사 후 6개월 후까지 테스트</strong>를 합니다.<br>신입 사원의 경험이 어떻게 개선이 됐는 지, 미래의 신입사원에게 어떻게 할 수 있는 지 파악하는 근거가 됩니다.</p><h4>케이스</h4><ul><li>구글 드라이브(Google Drive): 개선 후에 피드백을 직접 받습니다.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Paar4qWXoAs2dUPyMshdXA.jpeg" /><figcaption>구글 드라이브 팀이 받은 피드백 일부</figcaption></figure><ul><li>Etsy: 셀러가 샵을 만들었다가 취소하는 경우, 어떤 부분이 마음에 들지 않았는 지 물어봅니다.</li></ul><p>온보딩 프로젝트에서 가장 중요한 질문을 하고 마치겠습니다.</p><blockquote><strong>온보딩의 끝은 어디일까요?</strong></blockquote><h3>[음성 디자인에 힘을 전달하는 방법: 기존 문제에 대한 새로운 해결책 제시]</h3><p>Cheryl Platz — Amazon Echo Look 개발자, UX 대표 디자이너</p><p>몇 년간 시장에서 음성 인터페이스가 활발히 제공되고 있으나, 문제 해결을 하고 있지 않습니다. 기존에 해결했던 문제만을 해결하고 있습니다.</p><blockquote><strong>왜 음성 인터페이스를 사용해야 하는 걸까요?</strong></blockquote><p>사람들은 대화의 기술을 수천년 동안 진화, 개발되어 왔습니다. 대화는 생각하면서 쓰는 기술이 아니며 전혀 새로운 기술이 아닙니다.</p><p>2008년, 아이폰에 구글 보이스(Google Voice)를 탑재하면서 <strong>자연어 기술</strong>이 시작되었습니다.</p><ul><li>잘 설계된 자연어 인터페이스는 최소한의 연습만 있어도 사용할 수있습니다. 기술적 설계를 하지 않아도 편하게 대화하게 할 수있습니다. <strong>인간중심적</strong>인 기술입니다.</li><li>최근 현황: 더 자연스럽고 덜 기계적입니다. 같은 명령을 다양한 방식으로할 수있습니다.</li><li>화면 중심 생활에서 벗어나게 되었습니다.</li></ul><p><strong>고령인구 타겟으로 매력적인 기술</strong></p><ul><li>사람에게 익숙한 대화 기술로 디지털 기술을 사용할 수있습니다.</li><li>고령자에게 음성기술 채택률이 높습니다.</li><li>기술 진보에서 제외된 사람들에게 <strong>동일한 기술을 제공</strong>할 수있습니다.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tFyCEtWmQ7wD-g75rCcqnA.jpeg" /></figure><h4>음성기술을 타 팀에게 설득할 때 접근 방법</h4><ol><li>지금까지 전통적인 기술에서 배제됐던 고객을 찾아보기: 추가 고객 확보</li><li>음성 UI 시장의 궤도를 제시하기: 시장 규모가 상당히 큼</li><li>음성기술이 사용되는 맥락을 시나리오로 보여주기</li></ol><h3>자연어의 기본 개념 몇 가지</h3><ol><li>발화(Utterance): 고객이 내뱉는 문구</li><li>의도(Intent): 고객 요청의 숨은 의도</li><li>즉각 반응(Prompt): 고객에게 제공되는 시스템 반응</li><li>단어(Grammer): 자연어 시스템은 단어를 시작점으로 합니다. 단어를 배웁니다.</li></ol><p>자연어 시스템은 예측을 하고, 실시간 답변을 해야 합니다.<br>어떤 답이 나올 지 예측하기 어렵습니다. 오류에 대비한 디자인을 해야 합니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bw-S97XMUlbjX6PlqncVwg.jpeg" /></figure><ul><li>음성 기술은 지금의 모바일 기술처럼 중요한 기술이 될거라 생각합니다. 비주얼 아웃풋까지 아우르는 사람이 필요합니다.</li><li>음성 디자인은 새로운 개념이 아닙니다. <strong>오늘날의 음성 디자인은 기존에 오래된 문제를 해결하고 있습니다. 더 인간답고 편안하게 해결하고 있습니다.</strong></li></ul><blockquote>오래된 문제를 새롭게 해결하세요. 더 포괄적인 방법으로.<br>(Solve old problem in new, more inclusive ways)</blockquote><h3>[서비스 디자인으로 즐거움과 규모를 확장시키는 법]</h3><p>Nick Remis — Collective Health의 리드 디자이너</p><p>서비스 산업의 구조가 복잡하고 다양한 경로의 접점(Touch point)이 생기면서, 전체를 아우르는 서비스 디자인이 필요하게 되었습니다.</p><h4>서비스란 무엇인가</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_ogQMLRipbNUYnR-IBFS8g.jpeg" /></figure><ul><li>경제학자: 경제활동의 산물</li><li>서비스 디자이너: 하나의 조율된 시스템으로서 시간이 흐름에 따라서 전달이 되고, <strong>실체는 없지만 물리적인 증거</strong>들이 남습니다.</li><li><strong>애플: 누군가에게 도움을 주는 것.</strong></li></ul><h3>제품과 서비스의 차이과 특징</h3><h4>1. 소멸성</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mfYi1Ie3F3TxOEP_mNehLQ.jpeg" /></figure><p><strong>소프트웨어 CD(Software CD) VS 소프트웨어 클라우드 (Software Cloud)</strong><br>예전에는 소프트웨어를 물리적인 CD로 소비했습니다. 이젠 클라우드라는 서비스를 사용합니다. 구매와 환경, <strong>그 후까지 경험하는 서비스</strong>입니다.</p><p>만약 항공사가 사라진다면, 비행기와 공항이 있지만 아무도 이용할 수 없게 된다.</p><ul><li>서비스 블루프린트 (Service Blueprints)<br>고객경험과 과정을 다 살펴보는 툴입니다. 디자이너가 서비스가 지속될 수있도록 살펴볼 수있습니다.</li><li>발전 계획: 서비스 로드맵을 단계별로 설계할 수있습니다.</li></ul><h4>2. 관계중심(Relationship driven)</h4><p>제품은 판매를 하면 역할이 끝납니다. <strong>서비스는 계속해서 고객의 과정에 참여해야 합니다. </strong>그래서 수익과 직결이 됩니다.</p><ul><li>관계성이 단절된 사례 (Relationship breakdown)<br>ex) 페이스북은 광고주에 더 많이 투자합니다. 그렇게 사용자가 떠났습니다. 고객과의 관계가 무너지면 부정적인 영향이 드러납니다.</li></ul><h4>3. 프로세스와 만나는 접점(Touch point)이 조합을 이루면서 작동</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XxfcdcxEiRUFSPOdlprf0g.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*b5HXuHm70MFn1iHTSUkB4Q.jpeg" /></figure><ul><li><strong>조화, 조직된 경험(Orchestrated experiences)</strong><br>ex. 집카 렌트 서비스 (zipcars)<br>만나는 접점(Touch point)이 잘 연결된다면 고객경험이 완전히 달라질 수있습니다.</li><li><strong>생태계 지도(Ecosystem map)</strong>: 회사, 고객 내 뿐아니라 관계된 환경까지. 줌 아웃해서 연계된 모든 것을 봅니다.</li><li><strong>서비스 블루프린트(Service Blueprint)</strong>: 사용자가 한 조각에서 그 옆으로 어떻게 이동하며 연결해야하는 지 볼 수있습니다.</li></ul><h3>서비스를 디자인한다는 것 (Design a Service)</h3><ul><li>고객 경험에 집중합니다.</li><li>시간 흐름에 따라 반응과 경험, 응대 등까지 고려합니다.</li><li>그 조직 자체를 설계하게 됩니다. 회사의 문화가 사용자 경험까지 영향을 미칩니다.</li></ul><h3>서비스디자인 핵심 원칙</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZOi8c6D-mhaOJ4yCf58lnQ.jpeg" /></figure><ul><li><strong>인간 중심적:</strong> 사용자와 직원 경험을 고려합니다.</li><li><strong>상호 창조적인(Co-Creative):</strong> 함께 참여하며 창조합니다.</li><li><strong>세심히 조직된(Orchestrated)</strong>: 모두가 일련의 과정에서 조화를 이룹니다</li><li><strong>유형적인(Tangible)</strong>: 추상적인 것을 구체적으로 만들어 가치를 전달합니다.</li><li><strong>전체적인(Holistic)</strong>: 전체적인 관점을 가집니다. <strong>End to End를 고려</strong>해야 합니다.</li></ul><h3>서비스디자인 사고방식</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7K4Mmb1oedlFasNN6woR3g.jpeg" /></figure><p>뒤집기(Inside Out)방식으로 내부에서 밖을 바라보는 방식을 사용합니다.<br>큰 그림을 보지만, 다시 착륙한 것처럼 디테일한 부분까지 살핍니다.<br>서비스 디자이너는 촉진자(Facilitator) 역할을 합니다.</p><h3>협업 방법</h3><p>프로세스에서 자신의 목소리를 내서 서비스를 만들어 내는 경험이 중요합니다. 혼자서 만든다면 협업자가 이해하지 못하는 경우가 생깁니다. 모든 <strong>프로세스에서 함께 일합니다.</strong></p><h3>현대 조직에서 서비스 디자인</h3><ul><li>UX, UI 디자인 뿐 아니라 모든 것을 연결해주는 역할</li><li>어떤 역할을 해야하는 지 이해해야한다. 새로운 웹, 모바일이 어떻게 지원되어야하는 지 이해해야 합니다.</li><li>서비스는 아키텍트</li><li>이 물리적 공간에서 우리가 해야하는 것은 뭘까, 환경을 고려해야 합니다.</li><li>서비스 디자이너는 <strong>전통적인 방법을 대체하는 게 아니라, 더 강력하게 만듭니다. 더 고도화</strong>하는 것입니다.</li></ul><h3>[마치며]</h3><p>컨퍼런스를 통해 온보딩의 다양한 역할과 방법을 재밌게 들었습니다.</p><p>스타일쉐어에서는 현재 신규 사용자 유입을 위해 공격적으로 마케팅을 하고 있습니다. 하지만 정말 중요한 것은 유입 후 지속적으로 사용자를 관찰하는 것입니다. 그들이 어떤 여정을 거치는지, 또 어떻게 스쉐만의 가치를 전달받는 지에 대해 정확하게 파악하지 못한다면 이탈의 폭은 커질 수 밖에 없습니다.</p><p>온보딩은 단순히 사용자와 친해지는 교육의 역할 이상으로 <strong>가치를 제대로 전달하기 위한 일련의 설계</strong>라는 생각이 들었습니다. 장기적인 관점에서 만나는 접점(Touch point)마다 온보딩을 설계하면 서로를 학습하면서 사용자의 일상에 녹아드는 서비스가 될거라 생각합니다. 어쩌면 현실적인 브랜딩이라는 생각도 들고요.</p><p>서비스 디자인 세션은 실무에 바로 적용되는 내용은 아니었지만, 업무에 집중하던 일상으로부터 큰 그림으로 환기를 시켜주었습니다. 스타일쉐어는 모바일 앱(App)이 주 서비스지만, PC 웹 뿐 아니라 오프라인에서 올리브X 등 캠페인, 또 매년 DDP에서 대규모로 ‘마켓페스트&#39;에서 사용자와 만납니다.</p><p>그리고 사용자뿐 아니라 입점 브랜드와 광고주, 잠재 브랜드까지 다양한 이해관계자가 얽혀있습니다. 그 생태계에서 스타일쉐어는 어떤 접점에서 언제, 어떻게 가치를 전달할 것인지 서비스 디자인 관점에서 깊게 고민해 보아야 할 것같습니다.</p><p>참고: <a href="https://2019.uxdaysseoul.com/conference/">https://2019.uxdaysseoul.com/conference/</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3ebedae3136b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/styleshare/ux-days-seoul-2019-1-2-3ebedae3136b">UX DAYS Seoul 2019(1/2)</a> was originally published in <a href="https://medium.com/styleshare">StyleShare</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[나의 안드로이드 개발자 채용기]]></title>
            <link>https://medium.com/styleshare/%EB%82%98%EC%9D%98-%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%B1%84%EC%9A%A9%EA%B8%B0-f1e9c33508cb?source=rss----ed9cf866ec01---4</link>
            <guid isPermaLink="false">https://medium.com/p/f1e9c33508cb</guid>
            <category><![CDATA[안드로이드]]></category>
            <category><![CDATA[develop]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[채용]]></category>
            <category><![CDATA[engineering]]></category>
            <dc:creator><![CDATA[SeungyongYun]]></dc:creator>
            <pubDate>Mon, 15 Apr 2019 14:42:54 GMT</pubDate>
            <atom:updated>2019-04-16T03:11:53.127Z</atom:updated>
            <content:encoded><![CDATA[<p><em>“Droid Knights 2019 라이트닝 토크에서 발표한 내용을 요약한 글입니다.”</em></p><p>좋은 개발자를 모시기 위해 안드로이드 개발자로서 어떤 것들을 할 수 있을까요?</p><p>채용은 인사 담당자만의 몫이 아닙니다. 새로 들어온 팀원으로 인해 팀 퍼포먼스가 낮아지거나 (최악의 경우에는) 팀 분열이 일어날 수도 있고, 반대로 그 팀원과 ‘케미가 터져서’ 팀 퍼포먼스는 물론 개개인의 성장까지 이뤄낼 수도 있습니다. 가족이나 연인보다도 더 많은 시간을 함께하는 팀원에 대해서 우리가 수동적인 태도를 보이는 것은 적절하지 못하다고 생각합니다.</p><p>이 글을 통해 스타일쉐어 안드로이드팀에서 좋은 팀원을 모시기 위해 고민하고 경험했던 부분에 대해서 공유해보고자 합니다.</p><h4><strong>[STEP 1] 질문 하기: 우리는 어떤 사람을 원하는가?</strong></h4><p>위와 같은 질문에 대해 고민하지 않는 회사에서 근무한 적이 있었습니다. 단순히 ‘퍼포먼스 좋은 안드로이드 개발자’를 구하던 그들. 그 곳에서 저는 전반적인 채용 과정에서 실제로는 우리가 중요하게 생각하지 않는 엉뚱한 것에 집중하는 것을 자주 목격했습니다.</p><p>스타일쉐어에서는 이런 경험을 반복하고 싶지 않았습니다. 그래서 채용 준비의 첫 번째 단계로 <strong>‘우리가 어떤 사람을 원하는가?’, ’우리 팀에 어떤 문화를 심고 싶은가?’</strong>라는 질문에 대해 고민하고 팀원분과 의견을 나누며 <strong>인재상 문서</strong>를 작성했습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*iF2awkpJ8mvK4CIIZPrqNg.png" /></figure><p>이 문서를 토대로 지원하신 분들의 이력서를 검토했습니다. 확실히 문서화된 인재상을 기준으로 판단을 하니 팀원분과 의견 차이가 크지 않았고 그 덕에 수많은 이력서들을 보다 빠르게 판단할 수 있었습니다.</p><p>한 번은 고등학교 졸업예정인 스타일쉐어 유저가 안드로이드 개발자로 지원한 적이 있습니다. 원래대로라면 이 분은 면접을 볼 수 없었습니다. 내부적으로 신입개발자를 뽑겠다고 결정한 적은 없었기 때문이죠. 하지만 스타일쉐어의 실제 유저이며 고등학교에서 다양한 프로젝트를 진행한 경험 등 저희가 바라는 인재상에 부합하는 분이라 판단하여 면접을 진행하게 됐습니다. 여러 가지 이유로 인해 그분과 함께 하지는 못했지만, 이런 경험을 통해 제가 무의식중에 <strong>필수요소라고 여겼던 지원자의 경력이 사실은 우리 안드로이드 팀에게 크게 중요하지 않다</strong>는 결론을 얻게 됐습니다.</p><h4><strong>[STEP 2] 보여 주기: Job Description은 어떻게 작성해야하나?</strong></h4><p>생전 처음으로 Job Description(이하 JD)을 작성하려니 정말 어렵더군요. 그래서 원티드에 들어가서 ‘나는 이직을 할 거야!’ 라는 마음가짐으로 수십 개의 JD를 읽어본 뒤 매력적이라 느낀 JD들을 모아서 분석을 해봤습니다.</p><p>제가 끌리는 이력서는 이런 부분이 달랐습니다. 개발팀이 서비스를 개발함에 있어서 <strong>1)어떤 기술에 집중하는지 2)무엇을 가치 있게 여기는 팀인지</strong> 상세하게 적혀있었습니다. 그 JD를 읽으면 ‘내가 이 회사에 가게 되면 어떤 문화에서 어떤 부분을 중점적으로 다루게 되겠구나!’가 머릿속에 쉽게 그려졌습니다. <a href="https://brunch.co.kr/@8percent/23">8퍼센트 CTO님께서 작성하신 구인공고</a>도 매력적인 JD 중 하나였습니다.</p><p>HR 담당자께 전해 듣기론 제법 규모 있는 회사에서 JD 관련 지표를 측정한 결과, JD를 상세히 작성하고 난 뒤 JD 페이지를 통한 개발자의 지원율이 두 자릿수의 비율로 상승했다고 합니다.</p><p>그래서 저희는 <strong>프로젝트에서 사용하는 아키텍처에 대한 정보, 팀에서 중요시하는 가치, 새로운 기술에 대한 관심 등</strong>을 JD에 상세하게 작성했습니다. 그 덕분인지 콜드콜을 통해 JD를 전달받고 면접을 진행하신 분들이 꽤 있으며 ‘JD를 통해 StyleShare 개발 팀의 문화에 대해서 잘 알 수 있어서 좋았다.’, ‘입사 후 어떤 기술들을 사용하게 될 것인지 보다 확실하게 파악할 수 있어서 좋았다.’ 등의 긍정적인 피드백을 많이 받았습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cvZ3yB3wa1cIwOEUhkNKoA.png" /><figcaption><a href="https://www.notion.so/styleshare/Android-c2d5123eb5354906b834242736cc3a3b">https://www.notion.so/styleshare/Android-c2d5123eb5354906b834242736cc3a3b</a></figcaption></figure><h4><strong>[STEP 3] 속도 내기: 왜 프로젝트 과제는 빠지게 되었는가?</strong></h4><p>채용 초기에는 기술 면접 전 지원자분께 프로젝트 과제 제출을 요구했습니다. 지원자분의 ‘코딩 스타일’ 같이 이력서에서는 확인할 수 없는 다양한 부분들을 알 수 있었고, 과제 결과물을 통해 지원자분께서 앱의 어떤 부분에 중점을 두는지 쉽게 파악할 수 있었기 때문입니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kgDIzfH1eiZLf_1IUkujAQ.png" /></figure><p>하지만 프로젝트 과제 단계에서 이탈하는 지원자가 많았습니다. 파악해보니 ‘과제가 부담스러워서’ 보다는 과제 기간 도중에 다른 회사로 채용이 확정되는 경우가 대부분이었습니다. 이를 알게 된 팀원분께서 프로젝트 과제를 빼고 채용 프로세스를 진행해보는 것을 제안하셨습니다. 이에 대해 고민이 많았습니다만 이직을 준비하는 분들은 보통 한 회사에만 지원하시는 게 아니기 때문에 <strong>‘ 지원자분께서 비슷한 회사들 사이에서 고민하고 있다면 빠른 리듬의 채용 프로세스가 도움이 되지 않을까?’</strong>라는 결론에 도달했습니다. 그래서 프로젝트 과제 대신 스타일쉐어 서비스를 개발하다 마주할 수 있는 상황들을 퀴즈로 만들어 이를 보완하는 방향으로 채용 프로세스를 변경하게 됐습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mXF5w56BSfpb0e77RMxEyg.png" /></figure><p>변경 후 몇 차례 채용을 진행해보니 생각 이상으로 채용 과정이 훨씬 간결해졌습니다. 과제를 위한 이메일 커뮤니케이션, 과제 리뷰 등의 눈에 보이지 않던 비용들이 절감됐기 때문이었죠. 그 덕분인지 채용 프로세스 중에 이탈하는 케이스는 한 건도 발생하지 않았습니다. 게다가 프로젝트 과제 없이도 이력서에 적혀있는 GitHub 링크를 통해 코딩 스타일과 PR 리뷰까지 많은 부분을 확인할 수 있었습니다.</p><p>퀴즈에 대한 긍정적인 피드백도 많았습니다. 지원자분께서 문제를 해결해나가는 과정에서 추가적으로 얻을 수 있는 부분도 많았습니다. 퀴즈에서 요구하는 바가 모호한 경우 어떤 분께서는 ‘~상황을 가정했을 때’라는 말로 답변을 시작하셨고 어떤 분께서는 상황을 보다 명확하게 판단하기 위해 수차례 질문을 하시기도 하셨습니다. 이런 모습들을 통해 지원자분께서 저희와 함께 일을 할 때 어떤 모습을 가질 지 짐작할 수 있었습니다.</p><h4><strong>[STEP 4] 일정 잡기: 채용 시기는 언제가 적기일까?</strong></h4><p>스타일쉐어 안드로이드 채용 오픈을 결정한 시점이 작년 말이었고 1분기 이내에 안드로이드 개발자 1분을 채용하는 것이 목표였습니다. 1분기가 끝나갈 무렵인 3월 중순에 면접을 볼 땐 정해둔 기준에 많이 아쉬웠던 분도 어떻게든 뽑을만한 요소를 찾기위해 눈에 불을 밝히는 모습을 가지게 되더군요.</p><p>채용은 어렵고 시간이 오래 걸리는 일임을 분명히 알고 있었습니다. 그럼에도 기간을 정해두고 채용을 하려다 보니 일정이 촉박해질수록 현실과 타협하려는 마음이 자연스레 생기더군요. 하지만 앞으로 짧으면 6개월, 길면 몇 년도 함께 일할 분을 모시는 일에 타협은 있을 수 없었기에 고민 끝에 CTO님, PM님과 이와 관련하여 얘기를 나눈 뒤 여유를 확보했습니다.</p><p>타협하려던 저의 마음을 반성하며 이런 경험을 모바일 팀에 공유하고 이를 방지하기 위한 액션 플랜에 대해 논의를 했습니다. 입사 후 3개월은 회사와 프로젝트에 적응하는 시기이고, 최소 3개월은 보장이 돼야 의미 있는 수의 지원자분들을 만나 뵐 수 있으니 <strong>새로 오실 분의 역량이 필요한 시점보다 6개월은 일찍 채용을 시작해야 한다</strong>는 결론이 났습니다.</p><p>사실 이보다 더 일찍 준비하는 게 좋고, 가능하면 늘 채용에 대해 준비가 되어있어야 하는 것이 적절하다고 생각합니다. 좋은 개발자 채용의 기회는 결국 준비된 회사에 오기 마련이니까요.</p><p>앞서 말씀드린 고민과 경험을 통한 개선에도 불구하고 여전히 시행착오를 겪고 있습니다. 하지만 회를 거듭할수록 더욱더 좋은 방향으로 채용을 진행하고 있다고 생각합니다. 최근에는 안드로이드 채용 프로세스를 경험하신 개발자께서 다른 분께 스타일쉐어를 추천해주신 덕분에 iOS팀에 새로운 분이 지원해주신 적도 있었답니다.</p><p>중요한 것은 내가 <strong>지원자의 입장이 되어 생각해보는 것</strong>, 그리고 <strong>빠른 주기의 회고와 이를 통한 프로세스 개선</strong>이라 생각합니다. 이를 실천하기 위해 면접 마지막에는 늘 지원자분들께 채용 프로세스에 대한 피드백을 요청드리며, 이를 기반으로 회고하는 시간을 보냅니다.</p><p>또한 채용은 저희의 일방적인 평가가 아닌 <strong>지원자분과의 커뮤니케이션 과정</strong>이라 생각합니다. 그렇기에 면접 전에 회사로 놀러 오셔서 자유롭게 얘기를 나누기도 하고, 귀한 시간을 내어 면접 보신 분들께 저희의 기준에 근거하여 상세한 피드백을 드리려 노력하고 있습니다. 이런 과정에서 채용 프로세스 개선의 실마리를 얻기도 합니다.</p><p>채용을 진행하며 지원자분께 스타일쉐어를 개발 문화, 프로젝트 차원에서 어필하는 부분이 많습니다. 그러다보니 지원자분께서 기대하는 바와 실제 저희의 모습과의 차이가 크지 않기를 바라게 됩니다. 그래서 현재 팀 내 개발 프로세스에 대해서도 한 번 더 살펴보게되고, 프로젝트를 개선할 수 있는 최신 동향을 한 번 더 찾아보게되고, 기존 방식보다 더 개선할 부분은 없는지 살펴보게 되더군요. 또한 저희가 즐겁게 개발할 수 있는 바탕인 ‘자율’ 문화를 잘 유지하기 위해 개인적인 차원에서 어떠한 노력을 해야하는지도 고민하게 되구요.</p><p>이 뿐만이 아닙니다. 이렇게 채용 기준들을 정하고 이를 토대로 많은 개발자들을 만나뵙다 보니 제가 보완해야 할 부분들을 명확하게 파악할 수 있었습니다. 덕분에 안드로이드 개발자로서의 2019년 성장 플랜은 그 어느 해보다 수월하게 작성할 수 있었던 것 같습니다.</p><p>앞서 말씀드린 것처럼 채용의 과정은 어렵고 시간도 오래 걸리는 일임이 분명합니다. 하지만 함께 일할 분을 모시기 위해 끊임없이 고민하고 개선하려는 노력이 결과적으로는 회사의 프로젝트와 개인적인 발전의 발판 되어줄 뿐 아니라 정말 좋은 분과 함께 성장할 수 있는 결실까지 맺게 해준다고 생각합니다.</p><p>지금 이 순간에도 저처럼 좋은 분을 모시기 위해 많은 분들이 고민하고 여러 시도를 하고 계신 것으로 압니다. 이런 분들께 저의 짧은 채용기가 조금이나마 도움이 되기를 바라며 이 글을 마치도록 하겠습니다.</p><p>감사합니다.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f1e9c33508cb" width="1" height="1" alt=""><hr><p><a href="https://medium.com/styleshare/%EB%82%98%EC%9D%98-%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%B1%84%EC%9A%A9%EA%B8%B0-f1e9c33508cb">나의 안드로이드 개발자 채용기</a> was originally published in <a href="https://medium.com/styleshare">StyleShare</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[나는 이쁜 데일리룩을 보고 싶은걸? \w pose estimation]]></title>
            <link>https://medium.com/styleshare/%EB%82%98%EB%8A%94-%EC%9D%B4%EC%81%9C-%EB%8D%B0%EC%9D%BC%EB%A6%AC%EB%A3%A9%EC%9D%84-%EB%B3%B4%EA%B3%A0-%EC%8B%B6%EC%9D%80%EA%B1%B8-w-pose-estimation-7aa762522381?source=rss----ed9cf866ec01---4</link>
            <guid isPermaLink="false">https://medium.com/p/7aa762522381</guid>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[styleshare]]></category>
            <category><![CDATA[engineering]]></category>
            <category><![CDATA[pose-estimation]]></category>
            <category><![CDATA[deep-learning]]></category>
            <dc:creator><![CDATA[김동현]]></dc:creator>
            <pubDate>Thu, 13 Dec 2018 10:24:47 GMT</pubDate>
            <atom:updated>2018-12-14T07:57:18.818Z</atom:updated>
            <content:encoded><![CDATA[<p>안녕하세요. 스타일쉐어 백엔드 개발자 김동현입니다.</p><p>2018년의 스타일쉐어에서는 뷰티, 중고 그리고 데일리룩이라는 피드가 추가로 등장했는데요, 그중 제가 작업했던 데일리룩 피드를 만들게 된 배경과 개발 방향에 대해 공유드리고자 합니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xgf0X9wau0hSa4eNk2J0sQ.jpeg" /><figcaption>스타일쉐어 데일리룩</figcaption></figure><h3>#데일리룩 #ootd / 타자 치는 것은 귀찮아</h3><p>데일리룩에 관련된 스타일들만 뽑아내는 방법 중에 가장 간단한 방법은 텍스트로 분리해내는 방법이었을 것입니다.</p><p>하지만 #데일리룩 #ootd는 사진이나 내용이 관계가 없더라도 들어가 있는 경우가 많았습니다.</p><p>또한 위의 피드처럼 정성스러운 글을 써주는 유저도 많긴 했지만 자신의 데일리 로그를 남기면서 글을 작성하지 않는 경우도 더러 있었습니다.</p><p>즉, 단순히 텍스트로만 구별해내기에는 이미지에 대한 질을 확신할 수 없었고, 텍스트가 주된 서비스가 아니다 보니 설명 없는 좋은 이미지들이 많았는데요.</p><p>우리는 이 이미지들을 놓치고 싶지 않았습니다.</p><p>그래서 결과적으로 텍스트 대신 이미지를 사용하는 방향을 선택하게 되었습니다.</p><h3>이미지로 어떻게 구별해낼까?</h3><p>다행히도 R-CNN의 높은 인식률과 Pre-Trained 된 모델의 label 중 person이 이미 학습되어있던 터라 별도의 Transfer Learning 없이 이미지 내에서 body parts가 있는지 없는지 찾아내는 것은 아주 어렵지 않았습니다.</p><p>다만 문제가 있다면 body parts에 들어가는 모든 부분을 person이라고 예측하던 부분이었죠.</p><p>예를 들자면 아래와 같습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VOXwrKtk84eV1moBvf061g.jpeg" /></figure><p>다음과 같이 제가 사용한 모델에서는 body parts를 person이라는 라벨로 처리하고 있었습니다.</p><p>단순히 R-CNN의 person 라벨만을 믿기에는 의도했던 <strong>데일리룩</strong> 외에도 너무나도 많은 것들이 데일리룩이라는 이름으로 필터링될 것 같았습니다.</p><p>그래서 또 다른 필터가 하나 더 필요하다는 생각이 들었습니다.</p><h3>Pose Estimation</h3><p>Body Parts 중 우리가 원하는 부분이 사진에 있으면 좋겠다!라는 생각을 곰곰이 하다 보니 우연히 머릿속에 스쳐 지나가는 하나의 장면이 있었습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*-cieuY0G3tNeo6lGv2SWhA.png" /><figcaption>Source: <a href="http://graphics.berkeley.edu/papers/Kirk-SPE-2005-06/">http://graphics.berkeley.edu/papers/Kirk-SPE-2005-06/</a></figcaption></figure><p>바로 3D 모델링 중에서 Motion Tracker 에 관련된 장면이었는데요. 이것을 Tracker가 아니라 <strong>이미지에서 stick figure를 뽑아낼 수 있으면 되지 않을까?</strong>라는 생각이 들었습니다.</p><p>놀라운 딥러닝의 세계에는 이미 여러 명의 Stick Figure를 뽑아낼 수 있는 경지에 도달해 있었습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/540/1*vmqmdnVhrHIFt6wJNv2irA.gif" /><figcaption>Source: <a href="https://github.com/ZheC/Realtime_Multi-Person_Pose_Estimation">https://github.com/ZheC/Realtime_Multi-Person_Pose_Estimation</a></figcaption></figure><p>Pose Estimation 딥러닝 모델을 사용하여 아래와 같은 결과물을 얻어낼 수 있었는데요.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sPqPHUXB_cidHBs1_WKCoQ.jpeg" /></figure><p>이미지 내의 Body Parts의 존재 여부를 알게 되었으니 우리가 원하는 Body Parts가 이미지 내에 있는지 검사할 수 있게 되었습니다.</p><p>하지만 해당 모델이 마냥 가볍지는 않았기에 사용자의 업로드가 많은 순간에는 예측 Task가 밀리기 시작했습니다.</p><p>그래서 아주 단순하지만, 효과적인 아이디어들을 적용하였는데요.</p><p>pose estimation을 하기 전에 R-CNN을 돌린 후 person으로 예측된 bounding box가 있다면 pose estimation 모델을 돌리도록 했습니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*uwUxo8HdAw4M-zSL2JCWCQ.png" /></figure><p>하지만 위의 필터를 통했음에도 원하는 결과물이 안 나오는 경우가 종종 있었는데요.</p><p>바로 다음과 같은 경우입니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BFim06q4hp3swaom_CGteQ.jpeg" /></figure><p>생각보다 작은 사람의 stick figure도 잘 추출 내어서 해수욕장으로 떠나 찍은 사진 속의 저 멀리 있는 휴양객을 데일리룩으로 잡는 일이 종종 발생했거든요.</p><p>그래서 위의 조건에 더불어서 person이라고 예측된 bounding box size가 전체 이미지 크기 대비 n % 이상의 크기 일 경우 Pose Estimation을 진행하자는 것이었죠.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wCGbPpUyKNz8nPpdOArwHg.png" /></figure><p>적당한 크기 이상의 데일리룩들을 뽑아내고 싶었고 사람이 너무 작아서 안 보이는 경우도 피할 수 있었습니다.</p><p>빠른 분류 속도는 덤이었고요.</p><p>덕분에 유저들이 올린 콘텐츠 중 데일리룩이라는 범주에 속하는 콘텐츠를 잘 뽑아낼 수 있었습니다.</p><p>아래는 위의 과정을 거쳐서 Pose Estimation까지 처리되어 데일리룩 사진이라고 판별된 이미지입니다.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xs3Uwp40FzplqgjIfqs-YA.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GhlDjPFLzPG6mGbK_HjKxA.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*muvUIghA-TpUa0pILqcJxg.jpeg" /></figure><h3>이다음으론 무엇을 더 해볼 수 있을까요?</h3><p>사진 속의 자세를 알 수 있게 되었으니 좀 더 재밌는 것을 할 수 있을 것 같은데요.</p><p>예를 들면 K-Means를 적용하면 비슷한 모습의 데일리룩들만 모아볼 수도 있고 스타일쉐어 유저들이 자주 찍는 자세 라던가 유저 별 자세 선호도 등등 재밌는 것들을 할 수 있을 것 같습니다.</p><p><strong>날 따라 해 봐요</strong> 같은 것도 해볼 수 있겠네요 :)</p><h3>같이 해보지 않을래요?</h3><p>아직도 재밌는 것들이 많이 남은 스타일쉐어 에서는 더 많은 것을 하기 위해 개발자분들을 모시고 있습니다 :)</p><p>백엔드 개발자라고 해서 백엔드 개발에만 국한되지 않고 하고 싶은 것들을 해도 된다, 할 수 있다고 이야기해 주는 회사라고 생각합니다.</p><p>스타일쉐어를 좀 더 알고 싶으시다면 <a href="https://bit.ly/styleshare-careers">여기</a>를 눌러 주세요 :)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7aa762522381" width="1" height="1" alt=""><hr><p><a href="https://medium.com/styleshare/%EB%82%98%EB%8A%94-%EC%9D%B4%EC%81%9C-%EB%8D%B0%EC%9D%BC%EB%A6%AC%EB%A3%A9%EC%9D%84-%EB%B3%B4%EA%B3%A0-%EC%8B%B6%EC%9D%80%EA%B1%B8-w-pose-estimation-7aa762522381">나는 이쁜 데일리룩을 보고 싶은걸? \w pose estimation</a> was originally published in <a href="https://medium.com/styleshare">StyleShare</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[MySQL은 어떻게 동작 되는가?]]></title>
            <link>https://medium.com/styleshare/mysql%EC%9D%80-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%8F%99%EC%9E%91-%EB%90%98%EB%8A%94%EA%B0%80-672d49311816?source=rss----ed9cf866ec01---4</link>
            <guid isPermaLink="false">https://medium.com/p/672d49311816</guid>
            <dc:creator><![CDATA[StyleShare]]></dc:creator>
            <pubDate>Tue, 11 Dec 2018 05:42:35 GMT</pubDate>
            <atom:updated>2018-12-11T05:42:34.878Z</atom:updated>
            <content:encoded><![CDATA[<h4>조금은 진부하지만, 알면 좋은 것들</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/0*GFfnMZ1sESpT9uYs.jpg" /><figcaption>source: <a href="https://en.wikipedia.org/wiki/MySQL">https://en.wikipedia.org/wiki/MySQL</a></figcaption></figure><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fdocs.google.com%2Fpresentation%2Fembed%3Fid%3D1qQBWBNAnDGKJNWgwFYseScPFrSbaSaJlwPFJcjN8FIQ%26size%3Dl&amp;url=https%3A%2F%2Fdocs.google.com%2Fpresentation%2Fd%2F1qQBWBNAnDGKJNWgwFYseScPFrSbaSaJlwPFJcjN8FIQ%2Fedit&amp;image=https%3A%2F%2Flh3.googleusercontent.com%2FpYpH0-bdFoPWZkBjZZqWb1A-fVXm25W-dbJcDlut_Y_m4N1OeGXL8blS4eKPN5RXMCIAyQ%3Dw1200-h630-p&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=google" width="700" height="559" frameborder="0" scrolling="no"><a href="https://medium.com/media/386a7b55afe49459d76286239c8e32b1/href">https://medium.com/media/386a7b55afe49459d76286239c8e32b1/href</a></iframe><p>요즘은 다양한 DBMS 제품들이 시장에서 경쟁하고 있고, 다양한 기술이 선보이고 있지만, MySQL은 여전히 많이 사용되고 있는 DBMS입니다.</p><p>사실 AWS의 RDS와 같은 좋은 서비스에 ORM 같은 기술이 널리 사용되고 있는 요즘 같을 때, 이런 상식은 어쩌면 기억 저편에 있는 것이 좋을지도 모르겠습니다.</p><p>이런 이유로 조금은 진부한 이야기가 될 수 있지만, 개인적인 경험을 담아서, 사내에서 간단한 세미나를 하였습니다. 그리고 발표 자료를 이렇게 공개해보려 합니다.</p><p>발표 내용으로 전달하고자 하는 것은 “기본에 충실해지자”라는 원론적인 이야기입니다. 혹은 요즘은 추상화된 서비스를 정말 편리하게 이용할 수 있는 세상이긴 하지만, 기초적인 기술을 되돌아보는 시간을 가지기 위해 서 입니다.</p><p>그리고 실무적인 일에 집중하다 보면, 기초 기술에는 등한시하기가 쉬운데, 이러한 주제로 스터디 또는 발표를 하는 시간에는 현재 우리가 가지고 있는 기술 부채에 대해서 생각해 보는 시간이 되는, 그 나름대로 가치 있는 시간을 나눌 수 있다는 생각도 듭니다.</p><p>부족한 내용이지만 경청해준 팀원들에게 감사의 인사를 하며, 글을 마칩니다.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=672d49311816" width="1" height="1" alt=""><hr><p><a href="https://medium.com/styleshare/mysql%EC%9D%80-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%8F%99%EC%9E%91-%EB%90%98%EB%8A%94%EA%B0%80-672d49311816">MySQL은 어떻게 동작 되는가?</a> was originally published in <a href="https://medium.com/styleshare">StyleShare</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>