스토리 홈

인터뷰

피드

뉴스

조회수 1653

PyCon2017 첫번째날 후기

아침에 느지막이 일어났다. 어제 회사일로 피곤하기도 했지만 왠지 컨디션이 좋은 상태로 발표를 하러 가야지!라는 생각 때문에 깼던 잠을 다시 청했던것 같다. 일어나 아침식사를 하고 아이 둘과 와이프를 두고 집을 나섰다. 작년 파이콘에는 참가해서 티셔츠만 받고 아이들과 함께 그 옆에 있는 유아교육전을 갔었기에 이번에는 한참 전부터 와이프에게 양해를 구해둔 터였다.코엑스에 도착해서 파이콘 행사장으로 가까이 가면 갈수록 백팩을 메고, 면바지를 입고, 영어 글자가 쓰인 티셔츠를 입은 사람의 비율이 높아지는 것으로 보아 내가 제대로 찾아가고 있구나 라는 생각이 들었다.늦게 왔더니 한산하다.지난번에는 입구에서 에코백과 가방을 나눠줬던 것 같은데 이번에는 2층에서 나눠준다고 한다. 1층이 아무래도 복잡해지니 그런 것 같기도 하고, 2층에서 열리는 이벤트들에도 좀 더 관심을 가져줬으면 하는 것 같기도 하다. 우선 스피커 옷을 받고 싶어서 (솔직히 입고 다니고 싶어서) 2층에 있는 스피커방에 들어갔다.허락 받지 않고 사진찍기가 좀 그래서 옆방을 찍었다첫 번째 키노트는 놓쳤지만 두 번째 키노트는 꼭 듣고 싶었기에 간단히 인사만 하고 티셔츠를 들고 나왔다. (외국에서 오신 연사분과 영어로 대화를 나누고 있어서 자리를 피한것은 아니다.) 나가는 길에 보니 영코더(초등학교 5학년 부터 고등학생 까지 파이썬 교육을 하는 프로그램)을 진행하고 있었다. 의미있는 시도를 하고 있다는 생각이 들었다.이 친구들 2년 뒤에 나보다 잘할지도 모른다.키노트 발표장에 갔더니 아웃사이더님이 뒤에 서 게셨다. 지난 파이콘 때 뵙고 이번에 다시 뵈었으니 파이콘이 사람들을 이어주는 역할을 하는구나 싶었다.키노트에서는 현우 님의 노잼, 빅잼 발표 분석 이야기를 들을 수 있었다. 그리고 발표를 통해 괜히 이것저것 알려줘야만 할 것 같아 발표가 부담스러워지는 것 같다는 이야기를 들었다. 나 또한 뭔가 하나라도 지식을 전달해야 한다는 압박감을 느끼고 있었던 터라 현우 님의 키노트 발표를 듣고 나니 좀 더 오늘을 즐겨야겠다는 생각이 들었다.오늘은 재미있었습니다!현우님 키노트를 듣고 같은 시간(1시)에 발표를 하시는 경업님과 이한님 그리고 내일 발표이신 대명님, 파이콘 준비위원회를 하고 계신 연태님과 함께 식사를 하러 갔다. 가는 길에 두숟갈 스터디를 함께 하고 계신 현주님과 희진 님도 함께했다. 사실 이번에는 발표자도 티켓을 사야 한다고 해서 조금 삐져 있었는데 양일 점심 쿠폰을 주신다고 해서 삐진 마음이 눈 녹듯이 사라졌다.부담 부담식사를 하고 발표를 할 101방으로 들어가 봤다. 아직 아무도 없는 방이라 그런지 괜히 긴장감이 더 생기는 느낌이다. 발표 자료를 열어 처음부터 끝까지를 한번 넘겨 보고 다시 닫았다. 처음에는 가장 첫 발표라 불만이었는데 생각해보니 발표를 빨리 마치고 즐기는 게 훨씬 좋겠다는 생각이 들었다. 발표 자료를 다듬을까 하다가 집중이 되지 않아 밖으로 나갔다. “열린 공간” 현황판에 충동적으로 포스트잇을 하나 붙이고 왔다. 어차피 발표는 나중에 온라인으로도 볼 수 있으니까 사람들과 이야기를 나눠 봐야 겠다 싶었다. (내 발표에는 사람이 많이 왔으면 하면서도, 다른 사람의 발표는 온라인으로 보겠다는 이기적인 생각이라니..)진짜 궁금하긴 합니다다시 발표장으로 돌아왔다. 왠지 모르는 분들은 괜찮은데 아는 분들이 발표장에 와 계시니 괜히 더 불안하다. 다른 분들은 발표자료에 짤방도 많이 넣으셨던데.. 나는 짤방도 없는 노잼 발표인데.. 어찌해야 하나. 하지만 시간은 다가오고 발표를 시작했다.얼굴이 반짝 반짝리허설을 할 때 22분 정도 시간이 걸렸던 터라 조금 당겨서 진행을 했더니 발표를 거의 20분에 맞춰서 끝냈다. 그 뒤에 몇몇 분이 오셔서 질문을 해주셨다. 어리버리 대답을 한 것 같다. 여하튼 내 발표를 찾아오신 분들께 도움이 되었기를. 그리고 앞으로 좀 더 정확한 계산을 하시기를.대단히 발표 준비를 많이 하지도 못하면서 마음에 부담만 쌓아두고 있는 상황이었는데, 발표가 끝나니 아주 홀가분한 마음이 되었다. 발표장을 나가서 이제 부스를 돌아보기 시작했다. 매해 참여해 주고 계신 스마트스터디도 보이고 (정말 안 받고 싶은 ‘기술부채’도 받고 말았다.) 쿠팡, 레진 등 친숙한 회사들이 많이 보였다. 내년에는 우리 회사도 돈을 많이 벌어 여기에 부스를 내고 재미있는 이벤트를 하면 좋겠다는 생각이 들었다.부스를 돌아다니다가 이제 파이콘의 명물이 된 내 이름 찾기를 시작했다. 이름을 찾기가 쉽지가 않다. 매년 참여자가 늘어나서 올해는 거의 2000명에 다다른다고 하니 파이썬 커뮤니티의 성장이 놀랍다. 10년 전에 파이썬을 쓸 때에는 그리고 첫 번째 한국 파이콘이 열릴 때만 해도 꽤 마이너 한 느낌이었는데, 이제 주류가 된 것 같아 내 마음이 다 뿌듯하다. (그리고 내 밥줄이 이어질 수 있는 것 같아 역시 기쁘다)어디 한번 찾아보시라다음으로는 박영우님의 "Django admin site를 커스텀하여 적극적으로 활용하기” 발표를 들으러 갔다. (짧은 발표를 좋아한다.) 알고 있었던 것도 있었지만 커스텀이 가능한지 몰랐던 것들도 있어서 몇 개의 기능들을 킵해 두었다. 역시 컨퍼런스에 오면 내게 필요한 ‘새로운 것’에 대한 실마리를 주워가는 재미가 있다.익숙하다고 생각했지만 모르는것이 많다4시가 되어 OST(Open Space Talk)를 하기로 한 208B 방으로 조금 일찍 갔다. 주제가 뭐였는지는 잘 모르겠는데 주식 투자, Tensor Flow, 비트코인, 머신러닝 등등의 이야기들이 오가고 있었다. 4시가 되어 내가 정한 주제에 대해 관심 있는 사람들이 모였다. 괜히 모일 사람도 없는데 큰방을 잡은 것이 아닐까 하고 생각하고 있었는데, 생각보다 많은 분들이 오셨다.각 회사들이 어떤 도구를 사용하는지 설문조사도 해보고, 또 어떤 개발 방법론을 사용하는지, 코드 리뷰, QA는 어떻게 하고 있는지에 대한 이야기를 나눴다. 다양한 회사에서 다양한 일을 하는 사람들이 모여 있다 보니 생각보다 꽤 재미있게 논의가 진행되었다. 사실 내가 뭔가 말을 많이 해야 할 줄 알았는데, 이야기하고 싶은 분들이 많이 있어서 진행을 하는 역할만 하면 되었다. 마지막으로는 “우리 회사에서 잘 사용하고 있어서 다른 회사에도 추천해 주고 싶은 것”을 주제로 몇 가지 추천을 받은 것도 재미가 있었다.열심히 오간 대화를 적어두긴 했다5시에 OST를 마치고는 바로 집으로 돌아왔다. 오늘 저녁에 아이들을 잘 돌보고 집 청소도 열심히 해두어야 내일 파이콘에 참여할 수 있기 때문이다. 기대된다. 내일의 파이콘도.그리고 정말 감사드린다. 파이콘을 준비해주시고 운영해주고 계신 많은 분들께.#8퍼센트 #에잇퍼센트 #개발자 #개발 #파이썬 #Python #파이콘 #Pycon #이벤트참여 #참여후기 #후기
조회수 4919

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

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

AWS Rekognition + PHP를 이용한 이미지 분석 예제 (2/2)

이전 글 보기: AWS Rekognition + PHP를 이용한 이미지 분석 예제 (1/2)Overview지난 글에서는 AWS Rekognition을 이용해 S3 Bucket에 업로드한 이미지로 이미지 분석 결과를 확인했습니다. 이번엔 더 나아가 Collection(얼굴 모음)을 생성해보고, 얼굴 검색을 해보겠습니다.1. Collection 만들기Collection은 AWS Rekognition의 기본 리소스입니다., 생성되는 각각의 컬렉션에는 고유의 Amazon 리소스 이름(ARN)이 있습니다. 컬렉션이 있어야 얼굴들을 저장할 수 있습니다. 저는 ‘BrandiLabs’라는 이름의 Collection을 생성했습니다.1-1. createRekognition 메소드를 이용해 손쉽게 Collection 을 생성합니다.# 클라이언트 생성 $sdk = new \\Aws\\Sdk($sharedConfig); $rekognitionClient = $sdk->createRekognition(); # 모음(Collection) 이름 설정 $collection = array('CollectionId' => 'BrandiLabs'); $response = $rekognitionClient->createCollection($collection); 1-2. Collection이 정상적으로 생성되었다면 아래와 같은 응답을 받습니다.[ { "StatusCode" : 200 "CollectionArn" : "aws:rekognition:region:account-id:collection/BrandiLabs" /*...*/ } ] 2. Collection에 얼굴 추가IndexFaces 작업을 사용해 이미지에서 얼굴을 감지하고 모음에 추가할 수 있습니다. (JPEG 또는 PNG) 모음에 추가할 이미지에 대해서는 몇 가지의 권장사항[1]이 있습니다.두 눈이 잘 보이는 얼굴 이미지를 사용합니다.머리띠, 마스크 등 얼굴을 가리는 아이템을 피합니다.밝고 선명한 이미지를 사용합니다.권장사항에 최적화된 사진은 S3 Bucket 에 업로드되어 있어야 합니다. 미리 ‘kimwk-rekognition’ 이라는 이름으로 버킷을 생성 후 제 사진과 곽정섭 과장님의 사진을 업로드해두었습니다.2-1. IndexFaces 메소드를 이용해 얼굴을 추가합니다. 예시에서는 제 얼굴과 곽 과장님의 얼굴을 인덱싱했습니다.$imageInfo = array(); $imageInfo['S3Object']['Bucket'] = 'kimwk-rekognition'; $imageInfo['S3Object']['Name'] = 'kwakjs.jpg'; $parameter = array(); $parameter['Image'] = $imageInfo; $parameter['CollectionId'] = 'BrandiLabs'; $parameter['ExternalImageId'] = 'kwakjs'; $parameter['MaxFaces'] = 1; $parameter['QualityFilter'] = 'AUTO'; $parameter['DetectionAttributes'] = array('ALL'); $response = $rekognitionClient->indexFaces($parameter); 각각의 요청 항목에 대한 상세 설명은 아래와 같습니다.Image : 인덱싱 처리할 사진의 정보입니다.CollectionId : 사진을 인덱싱할 CollectionId 입니다.ExternalImageId : 추후 인식할 이미지와 인덱싱된 이미지를 연결할 ID 입니다.MaxFaces : 인덱싱되는 최대 얼굴 수 입니다. 작은 얼굴(ex. 배경에 서 있는 사람들의 얼굴)은 인덱싱하지 않고 싶을 때 유용합니다.QualityFilter : 화질을 기반으로 얼굴을 필터링하는 옵션입니다. 기본적으로 인덱싱은 저화질로 감지된 얼굴을 필터링합니다. AUTO를 지정하면 이러한 기본 설정을 명시적으로 선택할 수 있습니다. (AUTO | NONE)DetectionAttributes : 반환되는 얼굴 정보를 다 가져올 것인지 아닌지에 대한 옵션입니다. ALL 로 하면 모든 얼굴 정보를 받을 수 있지만 작업을 완료하는데 시간이 더 걸립니다. (DEFAULT | ALL)2-2. Collection에 정상적으로 얼굴이 추가되었다면 아래와 같은 응답을 받습니다. 사진 속 인물의 성별, 감정, 추정 나이 등의 정보를 확인할 수 있습니다.[ { "Face":{ "FaceId":"face-id", "BoundingBox":{ "Width":0.28771552443504333, "Height":0.3611610233783722, "Left":0.39002931118011475, "Top":0.21431422233581543 }, "ImageId":"image-id", "ExternalImageId":"kimwk", "Confidence":99.99978637695312 }, "FaceDetail":{ "BoundingBox":{ "Width":0.28771552443504333, "Height":0.3611610233783722, "Left":0.39002931118011475, "Top":0.21431422233581543 }, "AgeRange":{ "Low":20, "High":38 }, "Smile":{ "Value":false, "Confidence":85.35209655761719 }, "Eyeglasses":{ "Value":false, "Confidence":99.99824523925781 }, "Sunglasses":{ "Value":false, "Confidence":99.99994659423828 }, "Gender":{ "Value":"Male", "Confidence":99.35176849365234 }, "Beard":{ "Value":false, "Confidence":94.80714416503906 }, "Mustache":{ "Value":false, "Confidence":99.92304229736328 }, "EyesOpen":{ "Value":true, "Confidence":99.64280700683594 }, "MouthOpen":{ "Value":false, "Confidence":99.4529037475586 }, "Emotions":[ { "Type":"HAPPY", "Confidence":2.123939275741577 }, { "Type":"ANGRY", "Confidence":6.1253342628479 }, { "Type":"DISGUSTED", "Confidence":19.37765121459961 }, { "Type":"SURPRISED", "Confidence":7.136983394622803 }, { "Type":"CONFUSED", "Confidence":30.74079132080078 }, { "Type":"SAD", "Confidence":9.113149642944336 }, { "Type":"CALM", "Confidence":25.382152557373047 } ], "Landmarks":[ { "Type":"eyeLeft", "X":0.45368772745132446, "Y":0.31557807326316833 }, … ], "Pose":{ "Roll":5.615509986877441, "Yaw":-5.510941982269287, "Pitch":-17.47319793701172 }, "Quality":{ "Brightness":93.13915252685547, "Sharpness":78.64350128173828 }, "Confidence":99.99978637695312 } } ] 3. 얼굴 검색드디어 얼굴 검색의 시간이 왔습니다. searchFacesByImage 메소드를 이용하면 지금까지 그래왔던 것처럼 쉽게 얼굴 검색을 할 수 있습니다. 저는 ‘kimwk2.jpg’ 라는 또 다른 제 얼굴 사진을 S3 Bucket에 업로드해뒀습니다. 얼굴 검색이 제대로 이루어졌다면 응답으로 제 ExternalImageId (kimwk) 가 내려올 것입니다. 한 번 해볼까요?3-1. searchFacesByImage 메소드를 이용해 얼굴 검색을 합니다.$imageInfo = array(); $imageInfo['S3Object']['Bucket'] = 'kimwk-rekognition'; $imageInfo['S3Object']['Name'] = 'kimwk2.jpg'; $parameter = array(); $parameter['CollectionId'] = 'BrandiLabs'; $parameter['Image'] = $imageInfo; $parameter['FaceMatchThreshold'] = 70; $parameter['MaxFaces'] = 1; $response = $rekognitionClient->searchFacesByImage($parameter); 3-2. 정상적으로 검색이 되었다면 아래와 같은 응답을 받습니다.[ { "Similarity":99.04029083251953, "Face":{ "FaceId":"FaceId", "BoundingBox":{ "Width":0.23038800060749054, "Height":0.2689349949359894, "Left":0.2399519979953766, "Top":0.08848369866609573 }, "ImageId":"ImageId", "ExternalImageId":"kimwk", "Confidence":100 } } ] SearchFacesByImage는 기본적으로 알고리즘이 80% 이상의 유사성을 감지하는 얼굴을 반환합니다. 유사성은 얼굴이 검색하는 얼굴과 얼마나 일치하는지를 나타냅니다. FaceMatchThreshold 값을 조정하면 어느 정도까지 유사해야 같은 얼굴이라고 허용할지를 정할 수 있습니다.Conclusion이미지 분석 알고리즘과 얼굴 검색 기능을 직접 구현하려 했다면 시간이 많이 걸렸겠지만 AWS 서비스를 이용하면 이미지 분석을 금방 할 수 있습니다. 이 기능을 잘 활용하면 미아 찾기나 범죄 예방과 같은 공공 안전 및 법 진행 시나리오에도 응용할 수도 있겠죠. 다음엔 보다 재밌는 주제로 찾아오겠습니다.참고[1] 얼굴 인식 입력 이미지에 대한 권장 사항[2] Amazon Rekonition 개발자 안내서[3] 모든 예제는 AmazonRekognition, AmazonS3에 대한 권한이 있어야 함글김우경 대리 | R&D 개발1팀[email protected]브랜디, 오직 예쁜 옷만
조회수 1106

Vue, 어디까지 설치해봤니?

Overview새로운 사용환경 구축에 도전하는 건 개발자의 운명과도 같습니다. 오늘은 여러 장점을 가지고 있는 Vue (프론트엔드 자바스크립트 프레임워크)를 도전해보겠습니다. Vue는 다른 프레임워크에 비해 가볍고, 개발하기에 편합니다. 그럼 우선 Vue를 설치합시다! Vue 설치CDNhttps://unpkg.com/vue 주소를 script 태그에 직접 추가 Vue.js 파일다운개발용, 배포용 버전을 다운 받아 script 태그에 추가개발용 버전은 개발에 도움이 되는 모든 경고를 출력하기 때문에 개발 중에만 사용하고, 실제 서비스에서는 배포용 버전으로 사용해야 한다. NPM 설치규모가 큰 프로젝트 경우 컴포넌트별 독립적으로 관리할 수 있는 싱글 파일 컴포넌트 방식 추천 Vue를 설치하는 방법은 여러 가지가 있습니다. 각자 특성에 맞게 편리한 방법으로 설치해주세요. 이번 글에서는 싱글 파일 컴포넌트 방식을 사용할 것이므로 NPM vue-cli 를 설치해 프로젝트를 구성하겠습니다. # vue-cli 전역 설치, 권한에러시 sudo 추가 $ npm install vue-cli -global vue-clivue-cli를 사용하면 뷰 애플리케이션을 개발하기 위한 초기 프로젝트 구조를 쉽게 구성할 수 있습니다. 다만, 싱글 파일 컴포넌트 체계를 사용하려면 .vue 파일을 웹 브라우저가 인식할 수 있는 형태의 파일로 변환해 주는 웹팩(Webpack)이나 브라우저리파이(Browserify)와 같은 도구가 필요합니다. vue-cli 설치 명령어 vue init webpack : 고급 웹팩 기능을 활용한 프로젝트 구성 방식. 테스팅,문법 검사 등을 지원vue init webpack-simple : 웹팩 최소 기능을 활용한 프로젝트 구성 방식. 빠른 화면 프로토타이핑용vue init browserify : 고급 브라우저리파이 기능을 활용한 프로젝트 구성 방식. 테스팅,문법 검사 등을 지원vue init browserify-simple : 브라우저리파이 최소 기능을 활용한 프로젝트 구성 방식. 빠른 화면 프로토타이핑용vue init simple : 최소 뷰 기능만 들어간 HTML 파일 1개 생성vue init pwa : 웹팩 기반의 프로그레시브 웹 앱(PWA, Progressive Web App) 기능을 지원하는 뷰 프로젝트여러 설치 명령어 중에 특성에 맞는 초기 프로젝트를 생성하세요. 1) vue init webpack 실행# 해당 프로젝트 폴더에서 실행 $ vue init webpack   # 현재 디렉토리에서 프로젝트 생성 여부 ? Generate project in current directory? (Y/n) # 프로젝트 이름 ? Project name (vue_ex) # 프로젝트 설명 ? Project description (A Vue.js project) # 프로젝트 작성자 ? Author (곽정섭 ) # 빌드 방식 ? Vue build (Use arrow keys) # vue-router를 설치 여부 ? Install vue-router? (Y/n) # 코드를 보완하기 위해 ESLint를 사용 여부 ? Use ESLint to lint your code? (Y/n) # ESLint 사전 설정 선택 ? Pick an ESLint preset (Use arrow keys) # 단위 테스트 섧정 ? Set up unit tests (Y/n) # 테스트 러너 선택 ? Pick a test runner (Use arrow keys) # Nightwatch로 e2e 테스트를 설정 여부 ? Setup e2e tests with Nightwatch? (Y/n) # 프로젝트가 생성 된 후에`npm install`을 실행해야합니까? ? Should we run `npm install` for you after the project has been created? (recommended) (Use arrow keys) 2) 고급 웹팩 기능을 활용한 프로젝트 구성 방식으로 설치3) 설치완료4) package.json 파일에 설정된 라이브러리 설치$ npm install 5) 개발모드 실행# 해당 프로젝트 폴더에서 실행(소스수정시 자동 새로고침) $ npm run dev 6) http://localhost:8080/ 브라우저 실행7) Yeah, You got it!!!!추가 도구: Vue Devtools(크롬 확장 플러그인)Vue Devtools(크롬 확장 플러그인)은 Vue를 사용할 때, 브라우저에서 사용자 친화적으로 검사하고 디버그할 수 있습니다.크롬 개발자 도구에 Vue 탭이 추가됨ConclusionVue를 설치하는 여러 방법 중 고급 웹팩 기능을 활용한 프로젝트 구성을 알아봤습니다. 다음 글에서는 Vue 인스턴스 및 디렉티브(지시문) 사용법을 다뤄보겠습니다.참고설치방법 — Vue.js 글곽정섭 과장 | R&D 개발1팀[email protected]브랜디, 오직 예쁜 옷만#브랜디 #개발문화 #개발팀 #업무환경 #인사이트 #경험공유 #Vue
조회수 2129

[인공지능 in IT] 인공지능 기업에서 하드웨어 엔지니어로 사는 법

인공지능 열풍이 거세게 불면서 이를 개발하는 엔지니어에 대한 수요도 폭발적으로 늘었다. 글로벌 IT의 중심이라 불리던 실리콘밸리를 포함해 중국에서도 막대한 자본을 바탕으로 엔지니어에게 기존 연봉의 2~3배를 제공하는, '인재 쟁탈전'에 돌입했다. 암흑기라 불릴 정도로 이공계 기피현상이 심했던 과거 일은 어느새 기억 속에서 잊혀질만큼 소프트웨어 엔지니어의 위상은 날이 갈수록 높아지고 있다. 심지어 교과 과정에 코딩 교육 의무화를 논의하는 단계다.AI 전문인력이란, 대게 원천기술을 개발하는 소프트웨어 엔지니어나, 학문적인 연구를 하는 리서치 인력을 많이 생각한다. 하지만, 실제로 핵심적인 역할을 담당하는 사람은 하드웨어 엔지니어다. 일반적으로 하드웨어 엔지니어라고 하면 많은 사람들이 납땜을 하고, 모터를 돌리는 등 '기계'를 만지는 엔지니어를 떠올리지만(물론 이 역시 하드웨어 엔지니어가 하는 일 중 하나다), 요즘처럼 인공지능이 적용되지 않은 곳이 없는 세상에서 하드웨어 엔지니어 역할은 그 이상이다.모두의 이해를 돕고, 인공지능 기술을 만드는 회사에서 하드웨어 엔지니어 역할이 얼마나 중요한지 알 수 있도록, 스켈터랩스 사내에서 시니어 하드웨어 엔지니어로 일하고 있는 오혁님과 질의응답 시간을 가졌다.< 스켈터랩스 오혁 하드웨어 엔지니어 >하드웨어 엔지니어로서 주로 하고 있는 일은?사용자가 실제로 만질 수 있는 기기, NVIDIA에서 생산하는 하드웨어 플랫폼과 운영체제(OS) 등을 막론하고, 소프트웨어 알고리즘을 실제 프로덕트로 구현하는 일을 한다. 이런 면에서 보면 소프트웨어 엔지니어링 서포터라고 생각할 수 있다. 하지만, 많은 사람이 더욱 더 심층적으로 인공지능을 연구할 수 있는 이유는 바로 하드웨어의 발전 때문이다.< '구글I/O 2017'에서 차세대 인공지능 전용 칩 'TPU'를 발표하는 모습, 출처: 구글 >예를 들어보자. 프로세서(CPU) 연산속도는 계속 빨라지고 있고, 그래픽 프로세서(GPU)가 프로세서 역할을 일부 담당하고 있으며, 대용량 메모리, 인공지능 가속기 등 모든 면에서 하드웨어 성능이 뒷받침되어야 한다. 하드웨어가 없다면, 소프트웨어 엔지니어가 열심히 만들어도 실제 구현하기가 어렵다. 간단하게 정리하면 하드웨어 엔지니어로서 리서처 역할을 하고, 눈으로 보이는 하드웨어도 만든다.일반인들이 알고 있는 것과 가장 큰 차이가 있다면?일반적으로 하드웨어 엔지니어라고 하면 많은 사람이 빛을 내거나, 모터를 돌리고, 부품을 조립하는 등 물리적인 제품을 만든다고 생각한다. 맞는 말이다. 하지만, 이 모든것을 컨트롤하기 위한 펌웨어, 미들웨어, OS, 디바이스 드라이버 등 소프트웨어가 돌아가기 바로 직전 단계까지, 하드웨어 엔지니어가 담당한다. 또한, 실제 제품 구현도 우리가 맡는다. 때문에, 놀랍게도 하드웨어 엔지니어도 소프트웨어 엔지니어의 전유물이라고 여겨지는 코딩을 많이 한다.< 'GTC 2017'에서 엔비디아 젠슨 황 CEO가 고성능 GPU 아키텍쳐 '볼타'를 발표하고 있다, 출처: 동아일보 >인공지능 붐이 일어나면서 어떤 점이 달라졌는가?인공지능 열풍이 불기 전 하드웨어 엔지니어는 제품을 목적에 맞게 실행하는 역할을 주로 했다. 제품을 구동되기 위해서는 대부분 순차적으로 프로세스를 진행한다. 땜질하고, 코딩하고, 각 부품에 연동하면 완성되는 형태다. 그러나, 지금은 이런 기본적인 프로세스 외에도 기계학습에 대한 알고리즘이나 인공지능 기술 전반에 걸쳐 소프트웨어적인 기술을 이해하지 못하면 절대로 원활하게 제품을 구현할 수 없다. 소프트웨어 엔지니어링을 서포트하는 역할에서 벗어나 인공지능 기술에 들어가는 소프트웨어가 어떻게 구현되는지 이해해야 적합한 제품을 만들 수 있기 때문이다.심지어 이제는 펌웨어를 코딩하는 것도 예전과 많이 달라졌다. 결과물만 놓고 보면, 모터를 돌리는 것은 같을 수 있다. 하지만, 예전에는 로봇 팔을 만들어 무언가를 잡기 위해, A 모터와 B 모터를 순차적으로 돌려서 잡는 것에 그쳤다면, 이제는 기계학습을 적용해 어떤 종류의 컵이라도 스스로 알아서 잡을 수 있도록 제작한다. 하나하나 펌웨어로 낮은 레벨에서 구현하는 것이 아니라, 로봇팔이 잡았을 때 이에 맞는 조건을 제공, 코드 하나로 학습하는 커스터마이징을 적용하는 것이다.< 국산 복강경 로봇수술기기 '레보아이'의 모습, 출처: 동아일보 >인공지능 기업의 하드웨어 엔지니어로서 가장 재미있는 점은?인공지능을 적용하면서 굉장히 재미있는 것을 많이 시도할 수 있다. 아이디어를 내고 무언가를 만들고 싶다면, 최종 제품으로 가는 길에 있어 여러 옵션을 선택할 수 있기 때문이다. 다시 말해 인공지능 소프트웨어를 통해 기존과 다른 방식으로 문제에 접근하고, 이를 해결할 수 있다는 점이다. 비유하자면, 지금까지 손으로 직접 돌리는 드라이버를 사용했다면, 이제는 앞의 부품을 언제든 바꿔낄 수 있는 전동드릴을 사용하고 있다고 보면 된다.반대로 힘든 점은 무엇인가?아무래도 인공지능이 너무 핫하다 보니 계속해서 새로운 기술이 등장한다. 인공지능 업계에서 종사하는 모든 사람들도 마찬가지겠지만, 신기술을 공부하고 연구해야 좋은 제품을 만들 수 있다. 또한, 하드웨어 엔지니어들이 열심히 만든 결과물이 너무나도 빠른 기술 발전속도로 잠시 거쳐가는 것에 불과할까 걱정되기도 한다.그럼에도 앞으로 기대되는 점은 무엇인가?하드웨어 엔지니어로서 세상을 이롭게 하는 제품을 더 많이 제작할 수 있다는 점이다. 인공지능 기술이 발전함에 따라 인간이 못 하는 영역도 조금씩 다가서고 있다.개인적으로는 로봇 쪽에 관심이 많다. 기술 발전속도가 빨라지는 만큼 다양한 제품이 등장해 사람들의 삶에 많은 혜택을 줄 것으로 기대한다. 예를 들면, 청각 장애인을 위해 음성인식을 시각적으로 바꿔주는 제품이나, 거동이 불편한 독거노인을 돕기 위한 기술 등이 있다. 삶을 윤택하게 해주는 기술을 개발하는 것이 점점 더 쉬워지고 있다는 점에서 많이 기대하는 중이다. 어떤 형태가 될 지는 예측할 수 없지만, 지금 단계에서는 소프트웨어든 하드웨어든 커다란 인공지능 플랫폼을 만들고 있다고 생각한다.이호진, 스켈터랩스 마케팅 매니저조원규 전 구글코리아 R&D총괄 사장을 주축으로 구글, 삼성, 카이스트 AI 랩 출신들로 구성된 인공지능 기술 기업 스켈터랩스에서 마케팅을 담당하고 있다#스켈터랩스 #기업문화 #인사이트 #경험공유 #조직문화 #인공지능기업 #기술기업 #하드웨어엔지니어
조회수 1481

8퍼센트 CTO 1년 차 회고

2015년 11월 4일에 8퍼센트에 입사했으니 이제 1년이 되었다. CTO라는 직함을 달고 보낸 지난 1년을 뒤돌아 본다.1년전 첫번째 스프린트나는 무엇을 원했던가?회고를 할 때는 목표를 기준으로 지금을 살펴봐야 한다. 일 년 전에 썼던 8퍼센트에 입사하기까지 라는 글을 다시 꺼내어 보니 당시의 나는 이런 것들을 원했다. 성공하는 회사에 다닌다.개발 조직을 책임 지고 꿈꿔왔던 이상을 실험한다.회사 경영을 경험한다.사회에 도움이 되는 일을 한다.1) 성공하는 회사에 다닌다. 입사 전이라 "성공하는 회사에 다닌다”라고 적었지만 입사를 한 이상 “회사를 성공시킨다”라는 목표로 바꿔서 생각해도 좋겠다.2015년 10월 말을 기준으로 78.4억의 누적 대출액이 현재 기준으로 480억 가량 되니 지난 1년 동안 약 400억의 돈을 투자자로부터 대출자에게로 연결했다. 나는 이 돈의 크기가 정확히 8퍼센트라는 회사의 사회적인 영향력 그리고 고객들이 회사에 갖는 신뢰의 크기라고 생각한다. 또한 회사의 성공의 척도이다.그럼 이 400억이 성공을 이야기할 때 충분한가에 답을 해야 할터인데, 아직은 많이 부족하다. 하지만 어디인지 모르는 성공이라는 것에 다가갈 확률이 일 년 전에 비해 높아졌느냐라고 묻는다면 "그렇다"라고 자신 있게 말하겠다. 그리고 나 또한 그 확률을 높이는 것에 공헌하고 있다.입사할 당시에 대표님이 내세웠던 조건 중 하나가 올해 말 기준으로 500억이었는데, 그 기준은 넘기게 되었으니 80점을 주자.2) 개발 조직을 책임 지고 꿈꿔왔던 이상을 실험한다.입사 전에는 개발 조직만 맡을 것이라고 생각했으나, 현재는 더 넓은 프로덕트를 만드는 조직을 책임지고 있다. 1년 전에 꿈꿨던 이상이라는 것은 멋지게 일하는 조직이다. 입사 초기에는 이를 위해 꽤나 많은 노력을 했다. 회사 자체가 백지상태이기도 했고 의욕도 충만했다. 하지만 시간이 지나면서 나도 모르게 안주하게 되고 더 잘하기 위한 노력에 게을러졌다. 반성하자. 그래도 일 년 동안 데모를 한 번도 빠지지 않고 34차례 진행했다. (종종 프로젝트 진척이 잘 되지 않으면 데모에서 도망가고 싶다) 그리고 주기가 끝날 때마다 프로세스 개선을 위한 회고 회의를 해왔다. 비록 그 과정에 보완할 점은 많으나 포기하지 않고 프로세스를 일 년 동안 유지한 것에 점수를 주고 싶다. 이상에는 아직 멀었으나 이 조직이 내가 많은 것들을 실험할 수 있고, 그런 설득만 할 수 있다면 그 실험에 기꺼이 동참해 줄 수 있는 조직이라는 것을 깨달았다. 80점으로 시작해서 50점까지 내려갔다가 최근에 10점 정도를 얻었다. 60점을 준다.3) 회사 경영을 경험한다. 초기에 대표님의 신뢰를 얻는데 까지 시간이 꽤 걸렸다. 지금 생각해보면 서로 간의 신뢰를 쌓는데 시간이 걸리는 것은 자연스러운 것인데, 초기에는 의욕이 앞섰다. 왜 내게 더 많은 것을 맡기지 않는지가 불만스러웠다. 대표님이 내리는 결정의 많은 부분에 의심이 들었으며 딴지를 걸었다. 하지만 지금은 대표님의 선택과 결정이 대부분 이해되고 신뢰가 간다. 그리고 대표님이 내게 많은 것을 위임하고 믿어주는 것을 느낀다. 합이 맞아간다.생각보다 회사는 시장의 시간에 쫓겨  부족한 정보를 가지고 결정을 내려야만 했다. 회사의 결정이 모든 것을 좌우한다고 생각했었지만 이제는 결정에 따른 실행이 더 중요하다는 것을 알게 되었다. 4) 사회에 도움이 되는 일을 한다. 사회에 도움이 되는 일을 하는 것은 이 회사에 입사했을 때 결정이 되었다. 회사의 성장이 사회에 미치는 긍정적인 영향과 비례한다는 생각에는 변함이 없다. 이 회사의 존재가 이미 사회에 많은 영향을 미쳤다. 그리고 대부분은 긍정적인 영향이라고 생각한다. 90점을 주겠다.일하는 것의 변화 1) 일하는 양의 변화초기 반년은 후회가 없을 정도로 최선을 다해서 살았다. (내가 인생에서 이런 말을 할 수 있는 시기가 몇 번 없다.) 내 역량의 100%를 다하며 살았다. 그 6개월을 지난 이후에는 살짝 기어를 낮췄다. 좋게 말하면 마라톤을 위한 모드로 바꿨다고도 할 수 있고 어쩌면 6개월의 달리기로 조금 지쳤는지도 모르겠다. 2) 시간 분배의 변화처음 입사했을 때에는 시간의 50%를 개발에 사용했지만 지금은 10% 밖에 사용하지 못하고 나머지 40% 를 프로젝트 관리에 사용하고 있다. 30% 정도를 팀에 쓰고 있는데 처음에는 팀의 구조를 갖추는 데 사용했다면 지금은 팀을 운영하는 데 사용한다. 대체로 자리에 앉아 있는 시간이 많이 줄었고 내외부 사람들과 커뮤니케이션하는 시간이 늘어났다. (슬랙 통계를 보니 내가 압도적인 수다쟁이더라)나는 무엇을 배웠을까? 1) B2C 사업에서의 배움 기존에 일했던 회사는 B2B 회사였다. 손에 꼽을 수 있는 고객을 만족시키면 되었고 상대적으로 그들이 원하는 것은 명확했다. 혹은 커뮤니케이션을 통해 요구사항을 명확하게 만들 수 있었다. 상대적으로 긴 호흡으로 일을 했고, 성능이 중요했다.B2C 서비스는 달랐다. 고객은 어떤 면에서는 전혀 이성적이지 않았다. 놀라운 일이었다. 하지만 대부분 우리의 서비스는 냉정하게 평가되었다. 고객의 반응은 즉각적이지만 그 반응을 옳게 해석해서 제품에 반영하는 것은 어렵구나라는 것을 느꼈다. 지금 이 순간 고객을 최대로 만족시키는 선택이 회사에 있어 항상 옳은 선택은 아니라는 것도 알았다. 내가 개발하고 있는 서비스를 사용하는 많은 사람들이 있다는 것 그리고 사회에 직접적인 영향을 미친다는 것이 제품 개발을 지속할 수 있는 큰 동기가 된다는 것을 느꼈다.2) 프로덕트 책임자로서의 배움제품을 책임지고 있는 사람으로 B2C 서비스에 필요한 많은 역량이 부족하다는 것을 알게 되었다. 그리고 나의 부족한 역량이 완성도가 떨어지는 서비스에 많은 영향을 주고 있다는 것 또한 알게 되었다. 기획자와 일하는 경험, 디자이너와 일하는 경험 모두 처음이었다. 이를 통해 같은 회사에서 하나의 제품을 만들지만 그것을 바라보는 다양한 시각이 존재한다는 것을 알게 되었다.지난 회사의 CTO를 보며 제품의 문제를 어떻게 이렇게 잘 찾아낼까 생각했었는데 나 또한 그렇게 되더라. 통찰력이 아니라 관심을 얼마나 가지는가, 얼마나 책임감을 가지고 제품을 바라보는가에 대한 차이라는 것을 알게 되었다. 많은 기술적, 비즈니스에 기반한 결정을 했고, 그 결정의 결과를 지켜보고 있다. 그것에서 배웠다.3) 프로젝트 관리자로서의 배움 프로덕트팀이 일하는 방식으로 스크럼을 도입했다. 스크럼을 할 때 ScrumBut(우리는 스크럼을 해요. 하지만 이것저것은 하지 않아요.)을 유의하라는 말을 하는데 스크럼에서 요구하는 것들 중에서 하지 못한 것들이 꽤 있다. 예를 들면 업무의 양을 측정해서 번다운 차트를 제대로 그려가며 팀의 속도를 측정하거나,  업무를 항상 우선순위 기반으로 하는 것 등이다. 처음에는 시도했었으나 몇 번의 스프린트 후에는 적당히 스크럼을 적용하고 말았다. 프로젝트를 잘 관리하기 위해서는 많은 노력이 필요하다는 것을 알면서도 필요한 만큼의 노력을 기울이지 않은 것을 반성한다. 코딩을 포함한 회사에 많은 재미있을 것들에 우선순위를 두고 재미없음을 이유로 중요한 프로젝트의 관리를 뒤로 미루었다.4) 도구의 도입에서의 배움여러 가지 도구들을 도입했다. 모든 커뮤니케이션을 슬랙을 통하도록 여러 가지를 도입했다. 아마 우리 회사만큼 슬랙을 열심히 그리고 잘 쓰는 회사가 흔치 않을 것이라 생각한다.  컨플루언스를 도입해서 문서를 쓰는 문화를 만들어 갔다. 여전히 내가 제일 많은 문서를 쓰고, 대부분 내가 위키 가드닝(문서의 내용과 구조를 재조직하는 일)을 하고 있지만 사람들이 위키를 통해서 커뮤니케이션하는 것을 자연스럽게 생각하는 것을 보면 뿌듯하다. 트렐로도 도입해서 사용하고 있다. 최근까지는 엉성하게 쓰고 있었는 데 사용 가이드라인을 잡아서 한번 공유했으니, 앞으로 팀에 녹아들 것으로 기대한다.이렇게 도구를 도입하는 과정에서 변화를 이끌어 내는 방법을 연습했다. 사람들은 스스로 필요성을 느껴야 변화를 받아들인다. 탑다운식의 강압적인 도입은 결국 실패한다. 구성원들이 도구가 업무에 도움이 되는구나 라는 것을 느낄 때까지 선구자가 많은 노력을 기울여야 한다는 것을 알게 되었다. 사람들은 자신들이 필요한 정보를 컨플루언스에서 찾을 수 있을 때 자신도 정보를 컨플루언스에 남기기 시작했다. 자신들의 요청이 트렐로를 통해서 잘 처리된다는 것을 느꼈을 때 새로운 업무를 트렐로를 통해 전달해 주었다. 5) 개발에서의 배움초반에는 영역을 가리지 않고 개발을 했었다. 인프라 쪽도 정리하고 대출 프로세스도 개발하고 다른 금융업체와 연동도 하고 그리고 개발 환경도 갖추었다. 하지만 1년이 지난 지금 이미 내가 작성했던 코드는 절반 이상 다른 분들의 더 나은 코드로 대체되었다.타 금융권과 연계해서 개발을 하면서 이쪽 동네가 얼마나 기술 변화에 뒤쳐져 있는지를 알게 되었다. 취미로만 해봤던 웹 개발을 제품 레벨로 처음 해봤다. 프런트앤드 개발의 중요성과 어려움을 알게 되었다.개발팀의 효율을 올릴 수 있는 테스팅, 코드 리뷰, CI의 사용 등을 실제로 적용해 볼 수 있었다.마지막으로 회사에 좋은 분들을 모셔오면서 내가 얼마나 부족한 개발자인지를 알게 되었다.6) 금융업에서의 배움회사의 절반인 프로덕트를 만드는 사람들은 대부분 스타트업 출신이고, 나머지 절반은 금융권 출신으로 구성되어 있다. 금알못(금융을 알지 못하는 바보)으로 출발한 내가 이제 그들의 대화에 낄 수 있는 정도는 되었다. 하지만 여전히 하루가 멀다 하고 새로운 용어와 개념을 만나고, 대화가 끝나면 용어를 검색해보기 일쑤다.금융 동네는 어떤 경우에는 모든 것에 이유가 있어 딱딱 맞아떨어지는 것처럼 보이다가도 어떤 경우에는 도대체 이해가 안 되는 경우를 만나기도 한다. 여하튼 지난 일 년 동안 새로운 분야에서 일하면서 모르던 것(정확히는 모르는지도 몰랐던 것)들을  알아가는 즐거움을 느꼈다. 다음 회사를 가게 된다면 금융이 아닌 또 다른 분야에서 일하는 게 좋겠다는 생각이 들었다. 7) 채용에서의 배움입사했을 때 개발자 2명, 기획자 1명, 디자이너 1명이던 팀은 이제 개발자 9명에 기획자 2명, 디자이너 1명인 12명 팀이 되었다. 이 중 개발자 6명과 기획자 1명을 직접 채용했다. 이 과정에서 스타트업 채용의 어려움을 알게 되었고 조그만 노하우를 얻게 되었다. 그리고 채용에 따르는 책임이라는 것도 알게 되었다.채용 글을 쓰고 페이스북에 광고를 하고 구인 사이트에 올려보고 했지만 결국 대부분의 채용이 소개로 이루어졌다. 좋은 사람은 쉽게 다른 회사에 지원하지 않는다. 채용한 사람의 30배가 넘는 이력서를 받았고 5배가 넘는 면접을 보았다. 하지만 결국 소개를 받아 채용하는 것이 거의 유일한 방법인 것 같다. 회사에 대해 꾸준히 글을 써오고 있는데 이것이 채용에 많은 도움이 되었다.프로덕트팀 구성원은 내가 직접 채용을 결정하다 보니 이효진 대표에 의해서 내 인생이 바뀐 것처럼, 내가 채용한 사람들의 인생을 바꿨다. 그들이 자신들의 능력을 발휘해서 8퍼센트에 공헌할 수 있도록 하고 회사를 성공시켜서 그들의 노력에 답해 줄 수 있어야 한다는 생각을 한다. 8) 관리자로서의 배움 지난 회사에서 5명의 팀 리더를 할 때에는 내가 개발자인가 관리자인가라고 물으면 답하기가 쉽지 않았다. 하지만 지금 내게 묻는다면 나는 관리자라고 답하겠다. 나는 내 노력 50%를 들여서 전 구성원의 효율을 10% 더 올릴 수 있는 사람이 되어야 한다. 좋은 관리자였냐라고 하면 그렇지는 못했던 것 같다. 특히 구성원들에게 제때 필요한 피드백을 하지 못한 것은 아쉽다. 쓴소리를 해야 하는 위치에 있음에도 좋은 사람으로 남고 싶어서 적절한 때 적절한 피드백을 하지 못했다. 특히 같은 팀에 있는 디자이너와 기획자에게는 미안한 마음이다. 그들의 결과물에 대한 피드백도 쉽지 않았고, 커리어에 대해 해줄 수 있는 조언도 없었다. 그저 그들이 맡고 있는 좋은 프로덕트를 통해 성장해 나가길 바랄 뿐이다. 회사에서 1년 동안 "함께"라는 것을 기업 문화에 심기 위해 노력했다. 내가 시도했던 것들 중에 어떤 것들은 문화가 되어 정착이 되었고, 어떤 것들이 도태되어 사라졌다. 그 기준은 재미였다. 사람들에게 재미를 줄 수 있었던 슬랙의 #study 채널을 통해서 함께 공부하기, 브런치 매거진을 통해 함께 글쓰기, 2주에 한 번씩 오는 특별한 점심, 함께 하는 워크샵은 문화로 살아남았고 나머지는 사라졌다.  잃은 것은 무엇인가?1) 개발자로서의 경쟁력 개발자로서 경쟁력이 떨어지고 있다. 일반적으로 개발자가 망하는 과정을 다음과 같이 이야기한다.개발을 열심히 잘 하고 있음나이가 들면서 회사에서 관리자를 하라고 함관리자를 했더니 개발할 시간이 없어서 개발 실력이 떨어짐그 회사를 나오고 났더니 찾아 주는 곳이 없음치킨집내가 이런 과정으로 가고 있는 것은 아닐까? 에 대한 불안감이 있다. 전 회사에서는 새롭게 쏟아지는 기술들을 따라가며 공부를 해왔는데, 이제는 그런 공부 대신 당장 회사에 필요한 공부를 하게 된다. 이렇게 기술적인 경쟁력을 잃어 가게 되면 앞으로 먹고사는데 문제는 없을까?라는 생각도 들고, 당장 CTO라는 자리에서 옳은 결정들을 할 수 있을까 하는 생각 또한 든다.  2) 나와 가족체중을 얻었다. 운동할 시간이 없었기보다는 운동할 마음의 여유가 없었다. (둘 다 핑계이기는 매한가지다.) 체중이 늘어나다 보니 나 자신에 대한 자신감이 좀 떨어졌다. 가족들과는 입사 전에 비해 많은 시간을 보내지 못한다. 시간을 함께 보낼 때에도 핸드폰으로 슬랙을 확인하기 일쑤였다. 그리고 육체적/정신적으로 지친 상태라 100% 마음껏 놀아주지 못했다. 총평8퍼센트에 입사하기 전 일 년보다 훨씬 더 치열하게 살았다는 것만으로도 만족할 수 있는 1년이다. 내가 원하던 자리에서 원하던 경험을 할 수 있는 기회를 갖게 된 것만으로도 8퍼센트와 이효진 대표에게 감사한다. 자신 있게 추진하던 일 중 용두사미가 되어 버린 것들은 아쉽다. 하지만 용기 있게 많은 것들을 시도한 것은 잘했다. 내가 잘하는 것과 못하는 것이 여실히 드러난 1년이었다.   다음 1년은 무엇을 목표로 해야 할까?1) 회사를 성공시키자회사의 성장과 성공에 기대고 있는 것들이 너무나 많다. 지난 1년이 잽으로 탐색으로 해보는 1라운드였다면, 앞으로의 1년은 제대로 주먹을 뻗어보고 맞아보는 2라운드가 될 것으로 기대한다.  2) 그릇의 크기를 늘이자내 그릇의 크기에 따라 좋은 프로덕트, 구성원들의 성장, 채용이 좌우된다는 것을 알게 되었다. 그리고 입사 전보다 내가 갖춰야 할 역량들이 훨씬 명확해졌다. 꾸준히 갈고닦자.3) 더 멋지게 일하는 팀을 만들자 점점 손발이 맞아 간다. 더 많은 기회를 제공하고, 더 많은 것을 위임하자. 그리고 피드백을 잘하자. 이를 위해 끊임없이 실험하자.4) 손은 항상 더럽게지난 회사 CTO 님의 가장 큰 장점이 항상 손을 더럽게 유지하는 것이었다. 다시 말해 작더라도 일부 모듈을 직접 개발하고 다른 사람들의 코드들을 충분히 이해하셨다. 나 또한 다른 많은 일들이 있더라도 하루에 한 줄의 코딩은 할 수 있도록 하고, 다른 사람의 코드를 리뷰하는 데에도 시간을 쏟아야 하겠다.다시 맞이하는 1년회고를 통해 순식간에 지나간 지난 1년이 가볍지 않았다는 것을 알게 되었다. 다행이다. 이 글을 작성하면서 1년 전에 쓴  8퍼센트 입사 날을 읽어 보았다. 그날만큼은 아니지만 가슴이 두근거린다. 여전히 8퍼센트는 내게 모험이고 도전이다. 이제 새로운 마음으로 1년 1일 째를 맞이해야겠다. 지금 기분이라면 1년 뒤 더 멋진 회고글을 쓸 수 있을 것 같다.30번째쯤 스프린트의 데일리 미팅저와 함께 하고 싶은 개발자 분은 지원해 주세요! 기다리고 있습니다.#8퍼센트 #에잇퍼센트 #CTO #기업문화 #조직문화 #팀문화 #후기 #돌아보기 #개발자
조회수 981

비트윈 시스템 아키텍처

VCNC는 커플을 위한 모바일 앱 비트윈을 서비스하고 있습니다. 비트윈은 사진, 메모, 채팅, 기념일 등 다양한 기능을 제공하며, 오픈 베타 테스트를 시작한 2011년 11월부터 현재까지 연인 간의 소통을 돕고 있습니다. 그동안 비트윈 시스템 아키텍처에는 많은 변화가 있었으며 다양한 결정을 하였습니다. 비트윈 아키텍처를 발전시키면서 배우게 된 여러 가지 노하우를 정리하여 공유해보고자 합니다. 그리고 저희가 앞으로 나아갈 방향을 소개하려 합니다.소프트웨어 스택Java: 비트윈 API서버는 Java로 작성되어 있습니다. 이는 처음 비트윈 서버를 만들기 시작할 때, 서버 개발자가 가장 빨리 개발해낼 수 있는 언어로 프로그래밍을 시작했기 때문입니다. 지금도 자바를 가장 잘 다루는 서버 개발자가 많으므로 여전히 유효한 선택입니다.Netty: 대부분의 API는 HTTP로 호출되며, 채팅은 모바일 네트워크상에서의 전송 속도를 위해 TCP상에서 프로토콜을 구현했습니다. 두 가지 모두 Netty를 통해 사용자 요청을 처리합니다. Netty를 선택한 것은 뛰어난 성능과 서비스 구현 시 Thrift 서비스를 통해 HTTP와 TCP 프로토콜을 한 번에 구현하기 쉽다는 점 때문이었습니다.Thrift: API서버의 모든 서비스는 Thrift 서비스로 구현됩니다. 따라서 TCP뿐만 아니라 HTTP 또한 Thrift 인터페이스를 사용합니다. HTTP를 굳이 Thrift서비스로 구현한 이유는, TCP로 메세징 전송 시 똑같은 서비스를 그대로 사용하기 위함이었습니다. 덕분에 빠른 채팅 구현 시, 이미 구현된 서비스들을 그대로 사용할 수 있었습니다. 또한, 채팅 패킷들은 패킷 경량화를 위해 snappy로 압축하여 송수신합니다. 모바일 네트워크상에서는 패킷이 작아질수록 속도 향상에 크게 도움이 됩니다.HBase: 비트윈의 대부분 트랜젝션은 채팅에서 일어납니다. 수많은 메시지 트랜젝션을 처리하기 위해 HBase를 선택했으며, 당시 서버 개발자가 가장 익숙한 데이터베이스가 HBase였습니다. 서비스 초기부터 확장성을 고려했어야 했는데, RDBMS에서 확장성에 대해 생각하는 것보다는 당장 익숙한 HBase를 선택하고 운영하면서 나오는 문제들은 차차 해결하였습니다.ZooKeeper: 커플들을 여러 서버에 밸런싱하고 이 정보를 여러 서버에서 공유하기 위해 ZooKeeper를 이용합니다. Netflix에서 공개한 오픈 소스인 Curator를 이용하여 접근합니다.AWS비트윈은 AWS의 Tokyo리전에서 운영되고 있습니다. 처음에는 네트워크 및 성능상의 이유로 국내 IDC를 고려하기도 했으나 개발자들이 IDC 운영 경험이 거의 없는 것과, IDC의 실질적인 TCO가 높다는 문제로 클라우드 서비스를 이용하기로 하였습니다. 당시 클라우드 서비스 중에 가장 안정적이라고 생각했던 AWS 를 사용하기로 결정했었고, 지금도 계속 사용하고 있습니다.EC2: 비트윈의 여러 부가적인 서비스를 위해 다양한 종류의 인스턴스를 사용 중이지만, 메인 서비스를 운용하기 위해서는 c1.xlarge와 m2.4xlarge 인스턴스를 여러 대 사용하고 있습니다.API 서버: HTTP 파싱이나 이미지 리시아징등의 연산이 이 서버에서 일어납니다. 이 연산들은 CPU 가 가장 중요한 리소스이기 때문에, c1.xlarge를 사용하기로 했습니다.Database 서버: HDFS 데이터 노드와 HBase 리전 서버들이 떠있습니다. 여러 번의 테스트를 통해 IO가 병목임을 확인하였고, 따라서 모든 데이터를 최대한 메모리에 올리는 것이 가장 저렴한 설정이라는 것을 확인하였습니다. 이런 이유 때문에 68.4GB의 메모리를 가진 m2.4xlarge를 Database 서버로 사용하고 있습니다.EBS: 처음에는 HBase상 데이터를 모두 EBS에 저장하였습니다. 하지만 일정 시간 동안 EBS의 Latency가 갑자기 증가하는 등의 불안정한 경우가 자주 발생하여 개선 방법이 필요했는데, 데이터를 ephemeral storage에만 저장하기에는 안정성이 확인되지 않은 상태였습니다. 위의 두 가지 문제를 동시에 해결하기 위해서 HDFS multiple-rack 설정을 통해서 두 개의 복제본은 ephemeral storage에 저장하고 다른 하나의 복제본은 PIOPS EBS에 저장되도록 구성하여 EBS의 문제점들로부터의 영향을 최소화하였습니다.S3: 사용자들이 올리는 사진들은 s3에 저장됩니다. 사진의 s3키는 추측이 불가능하도록 랜덤하게 만들어집니다. 어차피 하나의 사진은 두 명밖에 받아가지 않고 클라이언트 로컬에 캐싱되기 때문에 CloudFront를 사용하지는 않습니다.ELB: HTTP는 사용자 요청의 분산과 SSL적용을 위해 ELB를 사용합니다. TCP는 TLS를 위해 ELB를 사용합니다. SSL/TLS 부분은 모두 AWS의 ELB를 이용하는데, 이는 API서버의 SSL/TLS처리에 대한 부담을 덜어주기 위함입니다.CloudWatch: 각 통신사와 리전에서 비트윈 서버로의 네트워크 상태와 서버 내의 요청 처리 시간 등의 메트릭을 CloudWatch로 모니터링 하고 있습니다. 따라서 네트워크 상태나 서버에 문제가 생긴 경우, 이메일 등을 통해 즉각 알게 되어, 문제 상황에 바로 대응하고 있습니다. Netflix의 Servo를 이용하여 모니터링 됩니다.현재의 아키텍처처음 클로즈드 베타 테스트때에는 사용자 수가 정해져 있었기 때문에 하나의 인스턴스로 운영되었습니다. 하지만 처음부터 인스턴스 숫자를 늘리는 것만으로도 서비스 규모를 쉽게 확장할 수 있는 아키텍쳐를 만들기 위한 고민을 하였습니다. 오픈 베타 이후에는 발생하는 트래픽에 필요한 만큼 여러 대의 유연하게 서버를 운영하였고, 현재 채팅은 TCP 위에서 구현한 프로토콜을 이용하여 서비스하고 있습니다.HTTP 요청은 하나의 ELB를 통해 여러 서버로 분산됩니다. 일반적인 ELB+HTTP 아키텍처와 동일합니다.채팅은 TCP 연결을 맺게 되는데, 각 커플은 특정 API 서버로 샤딩되어 특정 커플에 대한 요청을 하나의 서버가 담당합니다. 비트윈에서는 커플이 샤딩의 단위가 됩니다.이를 통해, 채팅 대화 내용 입력 중인지 여부와 같이 굉장히 빈번하게 값이 바뀌는 정보를 인메모리 캐싱할 수 있게 됩니다. 이런 정보는 휘발성이고 매우 자주 바뀌는 정보이므로, HBase에 저장하는 것은 매우 비효율적입니다.Consistent Hashing을 이용하여 커플을 각 서버에 샤딩합니다. 이는 서버가 추가되거나 줄어들 때, 리밸런싱되면서 서버간 이동되는 커플들의 수를 최소화 하기 위함입니다.클라이언트는 샤딩 정보를 바탕으로 특정 서버로 TCP연결을 맺게 되는데, 이를 위해 각 서버에 ELB가 하나씩 붙습니다. 어떤 서버로 연결을 맺어야 할지는 HTTP 혹은 TCP 프로토콜을 통해 알게 됩니다.Consistent Hashing을 위한 정보는 ZooKeeper를 통해 여러 서버간 공유됩니다. 이를 통해 서버의 수가 늘어나거나 줄어들게 되는 경우, 각 서버는 자신이 담당해야 하는 샤딩에 대한 변경 정보에 대해 즉각 알게 됩니다.이런 아키텍처의 단점은 다음과 같습니다.클라이언트가 자신이 어떤 서버로 붙어야 하는지 알아야 하기 때문에 프로토콜 및 아키텍처 복잡성이 높습니다.서버가 늘어나는 경우, 순식간에 많은 사용자 연결이 맺어지게 됩니다. 따라서 새로 추가되는 ELB는 Warm-up이 필요로 하며 이 때문에 Auto-Scale이 쉽지 않습니다.HBase에 Write연산시, 여러 서버로 복제가 일어나기 때문에, HA을 위한 Multi-AZ 구성을 하기가 어렵습니다.한정된 자원으로 동작 가능한 서버를 빨리 만들어내기 위해 이처럼 디자인하였습니다.미래의 아키텍처현재 아키텍처에 단점을 보완하기 위한 해결 방법을 생각해보았습니다.Haeinsa는 HBase상에서 트렌젝션을 제공하기 위해 개발 중인 프로젝트입니다. 구현 완료 후, 기능 테스트를 통과하였고, 퍼포먼스 테스트를 진행하고 있습니다. HBase상에서 트렌젝션이 가능하게 되면, 좀 더 복잡한 기능들을 빠르게 개발할 수 있습니다. 서비스에 곧 적용될 예정입니다.Multitier Architecture를 통해 클라이언트와 서버 간에 프로토콜을 단순화시킬 수 있습니다. 이 부분은 개발 초기부터 생각하던 부분인데, 그동안 개발을 하지 못하고 있다가, 지금은 구현을 시작하고 있습니다. 커플은 특정 Application 서버에서 담당하게 되므로, 인메모리 캐싱이 가능하게 됩니다. 클라이언트는 무조건 하나의 ELB만 바라보고 요청을 보내게 되고, Presentation 서버가 사용자 요청을 올바른 Application 서버로 릴레이 하게 됩니다.Multitier Architecture를 도입하면, 더 이상 ELB Warm-up이 필요하지 않게 되므로, Auto-Scale이 가능하게 되며, 좀 더 쉬운 배포가 가능하게 됩니다.Rocky는 API 서버의 Auto-Failover와 커플에 대한 샤딩을 직접 처리하는 기능을 가진 프로젝트입니다. 현재 설계가 어느 정도 진행되어 개발 중에 있습니다. 알람이 왔을 때 서버 팀이 마음을 놓고 편히 잠을 잘 수 있는 역할을 합니다.기본적인 것은 위에서 언급한 구조와 동일하지만 몇 가지 기능이 설정을 추가하면 Multi-AZ 구성이 가능합니다.특정 커플에 대한 모든 정보는 하나의 HBase Row에 담기게 됩니다.HBase의 특정 리전에 문제가 생긴 경우, 일정 시간이 지나면 자동으로 복구되긴 하지만 잠시 동안 시스템 전체에 문제가 생기가 됩니다. 이에 대해 Pinterest에서 Clustering보다는 Sharding이 더 낫다는 글을 쓰기도 했습니다. 이에 대한 해결책은 다음과 같습니다.원래는 Consistent Hashing을 사용하여 커플들을 Application 서버에 샤딩하였습니다. 하지만 이제는 HBase에서 Row를 각 리전에 수동으로 할당하고, 같은 리전에 할당된 Row에 저장된 커플들은 같은 Application 서버에 할당하도록 합니다.이 경우에, 같은 커플들을 담당하는 Application 서버와 HBase 리전 서버는 물리적으로 같은 머신에 둡니다.이렇게 구성 하는 경우, 특정 HBase 리전이나 Application 서버에 대한 장애는 특정 샤드에 국한되게 됩니다. 이와 같이 하나의 머신에 APP과 DB를 같이 두는 구성은 구글에서도 사용하는 방법입니다.이와 같이 구성하는 경우, Multi-AZ 구성이 가능하게 됩니다.AWS에서 같은 리전에서 서로 다른 Zone간 통신은 대략 2~3ms 정도 걸린다고 합니다.Presentation의 경우, 비동기식으로 동작하기 때문에 다른 리전으로 요청을 보내도 부담이 되지 않습니다.HBase에서 Write가 일어나면 여러 복제본을 만들게 됩니다. 하나의 사용자 요청에 대해 Write가 여러번 일어나기 때문에 HBase연산의 경우에는 서로 다른 Zone간 Latency가 부담으로 작용됩니다. Haeinsa가 적용되면, 한 트렌젝션에 대해서 연산을 Batch로 전송하기 때문에 AZ간 Latency 부담이 적습니다.저희는 언제나 타다 및 비트윈 서비스를 함께 만들며 기술적인 문제를 함께 풀어나갈 능력있는 개발자를 모시고 있습니다. 언제든 부담없이 [email protected]로 이메일을 주시기 바랍니다!
조회수 1163

클라우드와 운영자의 불안함.

2018년은 정말 클라우드가 일반화되는 해가 될듯 합니다. 클라우드 이전 사업 소식이 이곳저곳에서 들리는 요즘입니다. 스타트업 생태계는 이미 클라우드로 넘어갔지만 올해에는 엔터프라이즈 기업에서 대규모 IT 기업들까지 모두 클라우드로 넘어가고 있습니다. 와탭이 클라우드 최적화를 목표로 하는 모니터링 서비스이다보니 클라우드로 전환하는 시점에 있는 많은 기업들을 만나는데요. 클라우드를 적용하려고 준비중이거나 최근 클라우드로 이전한 기업의 운영팀들은 현업에서 사용하는 과정에서 클라우드 안정성에 대한 불안을 토로하기도 합니다. IT 운영자들이 느끼는 클라우드에 대한 불안감IT 운영의 핵심은 안정화입니다. 클라우드 이전까지 IT 인프라는 변화를 관리하는 대상이 아니였습니다. IT 인프라는 운영중에 변화하지 않으며 초기 설계에서도 최대 부하를 견디기에 충분한 여지를 남겨서 구성하였습니다. 하지만 클라우드에서는 IT 인프라가 운영중에도 변화 가능한 요소가 되면서 IT 인프라 규모 산정에서 부터 커다란 변화가 발생합니다. 최대 부하가 아닌 최소 부하가 규모 산정 기준이 되다. 여지껏 IT 인프라의 구성 기준은 언제나 최대 부하를 견딜수 있도록 설계되어왔습니다. 하지만 IT 인프라를 클라우드로 시작한 스타트업들이 IT 인프라를 구성하는 방법은 기존의 규칙을 무시하기 시작합니다. IT 인프라를 규모를 최소 부하에 맞춰서 구성하는 것입니다. 단지 실시간으로 확장 가능한 서비스 구조와 Auto Scailing을 통해 규모를 맞춰갑니다.IT 인프라 평균 부하의 기준이 높아지다. 클라우드 이전까지 우리는 IT 인프라의 CPU 부하율을 평소 20% 아래로 유지해 왔습니다. 하지만 이 또한 변화가 생깁니다. 제가 만나는 많은 클라우드 기반 서비스 기업들이 CPU 부하율을 50%에서 70%까지 유지하고 있었습니다. 일반적은 운영관점에서 IT 서비스 운영에 익숙하지 않은 기업의 운영 미숙이라 생각할 수 있습니다. 하지만 클라우드에 익숙한 운영팀은 서비스 성능에 문제가 발생하지 않는 범위에서 인프라의 규모를 실시간으로 조절합니다. 기존의 상식으로는 매우 위험해 보이지만 클라우드를 정말 잘 쓰는 기업들은 성능과 안정성을 해치지 않으면서 인프라 자원의 여유를 최대한 줄이는 방법들을 내재화하고 있습니다. IT 인프라 장애를 해결하지 않는다.  모든 IT 인프라는 장애가 발생합니다. 인프라의 장애는 이벤트성으로 발생하지만 운영팀은 장애를 반복 해결해 나가는 과정에서 패턴을 인지하고 대처해 나갑니다. 클라우드에서도 장애는 어쩔수 없이 발생하지만 운영팀은 장애를 인지할 뿐 장애를 물리적으로 해결하지는 않습니다. 대신 클라우드를 사용하는 IT 운영팀은 빠르게 서비스 구성과 환경을 전환하여 서비스를 원활하게 동작시킵니다. 운영자들이 갖는 불안감이 현실이 되다.다시 운영자들의 불안감에 대해서 이야기 해보죠. IT 인프라의 규모를 줄이고 자원 사용률이 평소에서 50%를 넘기는 급박한 사용 환경에서 클라우드 인프라에 장애가 발생해도 할 수 있는 일이 없다는 것은 정말 큰 스트레스를 주는 일입니다. 물론 위에서 설명한 것처럼 클라우드 네이티브한 서비스라면 문제없이 돌아갈 수 있겠지만 기존 레거시를 운영하면서 클라우드로 전환한다면 IT 운영자 입장에서는 앞에 이슈들이 불안감이 아닌 현실이 됩니다. 넷플릭스 7년만에 클라우드 이전을 완료하다.넷플릭스가 클라우드 이전을 결정한것은 2007년이지만 이전을 완료한것은 2016년이였습니다. 이렇게 긴 시간은 투자한 이유에 대해 넷플릭스는 "기존 IDC 기반의 인프라가 가진 문제들을 클라우드로 가져가지 않기 위해서"라고 했지만 다른 한편으로는 클라우드에서 발생하는 문제들을 해결할 수 있는 시스템 구조를 만들기 위해서였습니다. 그렇기 때문에 넷플릭스에서는 클라우드 네이티브 방식을 택하여 사실상 모든 기술을 재구축하고 운영 방식을 근본적으로 바꿨다. 아키텍처 면에서 넷플릭스는 거대한 앱을 수백 개의 마이크로 서비스로 마이그레이션하고 NoSQL 데이터베이스를 사용하여 데이터 모델을 반정규화했다. 예산 승인, 중앙화된 릴리스 관리, 몇 주에 걸친 하드웨어 프로비저닝 주기를 도입해 지속적인 콘텐츠 전달이 가능해졌으며, 느슨하게 결합된 개발운영(DevOps) 환경에서 엔지니어링 팀이 셀프서비스 툴로 독립적인 결정을 내릴 수 있게 되면서 혁신이 가속화되었다. 이 과정에서 새로운 시스템을 여럿 구축해야 했으며, 새로운 기술도 배워야 했다. 넷플릭스가 클라우드 네이티브 기업으로 변신하는 데는 많은 시간과 노력이 필요했지만, 클라우드 마이그레이션을 통해 글로벌 TV 네트워크로서 지속적인 성장을 이뤄나갈 밑거름을 마련할 수 있었다.https://media.netflix.com/ko/company-blog/completing-the-netflix-cloud-migration결론기존의 레거시를 바탕으로 클라우드 마이그레이션을 진행하는 기업들은 클라우드에서 발생하는 다양한 운영 이슈들을 겪을 수 밖에 없습니다. 대부분 클라우드 이전 사업을 진행하는 데 있어서 이전 서비스 성능을 맞추는 데만 집중하다보니 이전 후 운영과정에서 발생하는 많은 문제들은 운영팀이 짊어지게 됩니다. 하지만 이 문제들은 개발팀과 운영팀이 함께 지속적으로 개선해 나가야 합니다. 최종적으로 클라우드 네이티브 구조가 완성되기 위해서는 시스템과 조직 문화 모두가 변화해야 합니다. 클라우드 마이그레이션은 엄청 고난한 일입니다. 만일 클라우드를 도입했는데, 아직 불안함이 있다면 아직 클라우드 마이그레이션이 끝나지 않은것입니다. #와탭랩스 #개발자 #개발팀 #인사이트 #경험공유 #일지
조회수 22546

Next.js 튜토리얼 9편: 배포하기

* 이 글은 Next.js의 공식 튜토리얼을 번역한 글입니다.** 오역 및 오탈자가 있을 수 있습니다. 발견하시면 제보해주세요!목차1편: 시작하기 2편: 페이지 이동 3편: 공유 컴포넌트4편: 동적 페이지5편: 라우트 마스킹6편: 서버 사이드7편: 데이터 가져오기8편: 컴포넌트 스타일링9편: 배포하기 - 현재 글개요아래와 같은 궁금증이 생긴 적이 있나요?어떻게 내가 만든 Next.js 애플리케이션을 배포할 수 있나요?아직 배포에 대해 이야기하지 않았지만 배포하는 것은 꽤 간단하고 직관적입니다.Node.js를 동작할 수 있는 곳이라면 어디든 Next.js 애플리케이션을 배포할 수 있습니다. 매우 간단한 ▲ZEIT now로 배포하는 데에도 불구하고 어떤 잠금 장치도 없습니다.설치이번 장에서는 간단한 Next.js 애플리케이션이 필요합니다. 다음의 샘플 애플리케이션을 다운받아주세요:아래의 명령어로 실행시킬 수 있습니다:이제 http://localhost:3000로 이동하여 애플리케이션에 접근할 수 있습니다.Build와 Start처음으로 프로덕션에 우리의 Next.js 애플리케이션을 빌드해야 합니다. 빌드는 최적화된 프로덕션의 코드 세트를 생산합니다.이를 위해 간단히 다음의 npm 스크립트를 추가하세요:그런 다음 하나의 포트에서 Next.js를 시작해야 합니다. 사이드 렌더링을 수행하고 페이지를 제공합니다. (위의 명령으로 빌드됩니다)이를 위해 다음의 npm 스크립트를 추가하세요:이러면 3000 포트에서 우리의 애플리케이션이 시작됩니다.이제 프로덕션에서 애플리케이션을 동작시키 위해 다음의 명령어를 실행할 수 있습니다:두 개의 인스턴스 실행하기애플리케이션의 인스턴스 두 개를 실행시켜 봅시다. 대부분 앱을 수평으로 확장하기 위해 이 작업을 수행합니다. 처음으로 start npm 스크립트를 다음과 같이 변경해봅시다:만약 Winodws라면 next start -p %PORT%로 스크립트를 변경해야 합니다.이제 애플리케이션을 처음으로 빌드해봅시다.npm run build그러면 터미널에서 다음의 명령어로 실행시켜 봅시다:PORT=8000 npm startPORT=9000 npm startWinodws에서는 다른 명령어를 실행시켜야 합니다. 하나의 옵션은 애플리케이션에 cross-env npm 모듈을 설치하는 것입니다.그런 다음 커맨드 라인에서 cross-env PORT=9000 npm start를 동작시켜 주세요.두 개의 포트 모두에서 애플리케이션에 접근할 수 있나요?- 네. http://localhost:8000와 http://localhost:9000 둘 다 접근할 수 있습니다.- http://localhost:8000에서만 접근 가능합니다.- http://localhost:9000에서만 접근 가능합니다.- 둘 다 접근할 수 없습니다.한 번의 빌드로 많은 인스턴스 실행시키기보다시피 애플리케이션을 한 번 빌드해야 합니다. 그런 다음 원하는만큼의 많은 포트들을 시작할 수 있습니다.▲ZEIT now에 배포하기Next.js 애플리케이션을 빌드하고 시작하는 방법을 배웠습니다. npm 스크립트를 사용하여 모든 것을 수행했습니다. 그래서 원하는 배포 서비스를 사용해서 동작하도록 애플리케이션을 설정할 수 있습니다.하지만 ▲ZEIT now를 사용하면 딱 한 번의 과정만 수행하면 됩니다.다음과 같은 npm 스크립트만 추가해주세요:그런 다음 now를 설치해주세요. 설치 후 다음 명령어를 적용해주세요:now기본적으로 애플리케이션의 루트 디렉터리 안에서 "now" 명령어를 실행합니다.여기에서 애플리케이션을 시작하는 포트로 8000 포트를 지정했지만 ZEIT now에 배포할 때 변경하지 않았습니다.그러면 ZEIT now에 배포할 때 애플리케이션에 접근할 수 있는 포트는 어떤 것일까요?- 8000- 443 (혹은 언급되는 포트가 없음)- URL에 언급한 모든 포트- 에러를 표시한다. "443 포트에서만 시작할 수 있습니다"ZEIT는 항상 443 포트를 사용합니다실제로 8000 포트에서 애플리케이션을 시작해도 now에 배포될 때는 443 포트를 사용해서 접근할 수 있습니다. ("https" 웹사이트의 기본 포트)이것은 ▲ZEIT now의 특징입니다. 원하는 포트에서 애플리케이션을 시작해야 합니다. ▲ZEIT now는 항상 443 포트로 매핑합니다.로컬에서 애플리케이션 빌드하기▲ZEIT now는 npm build 스크립트를 발견하고 빌드 인프라 내부에 빌드합니다.하지만 모든 호스팅 제공자가 이와 같은 것을 가지고 있지는 않습니다.이 경우 로컬에서 다음의 명령어를 사용해서 빌드할 수 있습니다:npm run build그런 다음 .next 디렉터리를 사용하여 애플리케이션을 배포하세요.커스텀 서버를 사용하여 애플리케이션 배포하기우리가 막 배포한 애플리케이션은 커스텀 서버 코드를 사용하지 않았습니다. 하지만 만약 사용한 경우에는 어떻게 배포할 수 있을까요?다음의 브랜치로 체크아웃하세요:커스텀 서버를 사용하여 애플리케이션을 실행하기 위해 애플리케이션에 Express를 추가해주세요:npm install --save express애플리케이션 빌드하기이를 위해 next build를 사용하여 애플리케이션을 배포할 수 있습니다. 다음의 npm 스크립트를 추가해주세요:애플리케이션 시작하기프로덕션 애플리케이션임을 알리기 위해 커스텀 서버 코드를 생성해야 합니다.이를 위해 server.js로부터 이 코드를 살펴봅시다.이 부분을 살펴봅시다:그러면 프로덕션으로 이와 같이 애플리케이션을 시작할 수 있습니다.그래서 "npm start" 스크립트는 다음처럼 변경됩니다:마무리Next.js 애플리케이션을 배포하는 것에 대해 거의 다 배웠습니다.문서에서 Next.js 배포하기에 대해 더 배울 수 있습니다.배포에 대한 질문이 있다면 자유롭게 Slack에서 물어보거나 issue를 제출하세요.#트레바리 #개발자 #안드로이드 #앱개발 #Next.js #백엔드 #인사이트 #경험공유
조회수 3629

린더를 만들고 있는 이유 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위권에 오른 이번 사건이 완전히 새로운 형태의 일정 구독 플랫폼의 시작을 알리는 출발선이 되었으면 한다. 다시 또 높은 순위권으로 올라오기 위해서는 아마 한동안 많은 노력들이 필요로 될 것으로 예상되기에, 우리는 앞으로도 화장품 세일, 아이돌 스케줄, 대학교 학사일정, 스포츠 경기, 마트 휴무일, 공연, 전시 등을 넘어 사람들이 필요로 하는 새로운 일정 컨텐츠를 찾아 헤맬것이다.세상 사람 모두가 일정을 받아보는 날이 오기를 꿈꾸며, 와, 근데 이번 여름밤은 정말 더워도 너무 덥다.#히든트랙 #챗봇 #기술기업 #개발자 #개발팀 #인사이트 #경험공유
조회수 1656

자바스크립트 기초 문법 정리 Part 1

웹 프로젝트 경험은 많지 않아서 JavaScript(이후 '자바스크립트'로 통칭)를 많이 다뤄보지 못했다. 그래서 Node.js(이후 '노드'로 통칭)를 배우기 전에 자바스크립트 기초 문법을 먼저 정리하고 시작하려고 한다. 이후 계속 노드를 공부하면서 자바스크립트에 대해서도 꾸준히 공부하고 정리할 예정이다.간략하게 정리를 한 글이니 혹시나 개발을 처음 공부하시는 분들은 다른 가이드를 찾아보시는 게 적합할 듯합니다. 이 글은 다른 개발 언어에 대한 경험이 있으신 저와 같은 상황인 분들이 빠르게 자바스크립트를 훑고 넘어가기 좋도록 정리하였습니다.출력[removed]("Hello World!");주석// 한 줄 주석/* 여러 줄주석*/<!-- HTML 주석 -->외부 자바스크립트 연동 - 기본형[removed][removed]변수변수에 저장할 수 있는 데이터의 종류: String / Number / Boolean / Nullvar message;    message = "Hello World!";문자열 안에 HTML 태그를 포함하여 출력하면 태그로 인식되어 출력됨var tag="Tag!!";문자열 데이터에서 숫자열 데이터로 바꾸는 경우var num=Number("7");논리형 데이터 var isChecked=true;var isSmall=150>100;  // truevar string=Boolean("hi");   // 0과 null을 제외한 모든 데이터 true 반환typeof변수에 저장된 데이터형 추출var num=10;[removed](typeof num);    // number가 출력됨비교 연산자다른 연산자들은 타 언어들과 동일하여 생략.var a=10;var b="10";// 데이터형과 무관하게 표기된 숫자만 비교[removed](a==b);   // true[removed](a!=b);    // false// 데이터형도 반영하여 비교[removed](a===b);   // false[removed](a!==b);    // true제어문Java의 문법과 동일if(조건식) {    실행문;} else if(조건식 2) {    실행문 2;} else {    실행문 3;}var 변수=초깃값;switch(변수) {    case 값 1:        실행문 1;        break;    case 값 2:         실행문 2;        break;    default:        실행문 3;var 변수=초깃값;while(조건식) {    실행문;    증감식;}var 변수=초깃값;do {    실행문;    증감식;} while(조건식)for(초깂값; 조건식; 증감식) {    실행문;}여기까지가 '자바스크립트 기초 문법 정리 Part 1'이후 포스팅에서는 자바스크립트의 객체와 함수, 이벤트에 대해 다룰 예정이다.각 객체에서 지원하는 메서드에 대해서는 이번 포스팅보다는 좀 더 자세하게 각 메서드에 대한 기능까지 정리할 것이다. 후에 이벤트까지 정리가 끝나면 보다 간략하게 한 게시글에서 확인할 수 있도록 모든 파트를 통합한 게시글을 포스팅해보자!참고문헌:Do it! 자바스크립트+제이쿼리 입문 - 정인용티스토리 블로그와 동시에 포스팅을 진행하고 있습니다.http://madeitwantit.tistory.com#트레바리 #개발자 #안드로이드 #앱개발 #Node.js #백엔드 #인사이트 #경험공유
조회수 1460

확률론적 프로그래밍 언어는 왜 필요 할까요?

AI•머신러닝은 모든 분야에서 거론되며 이를 적용해볼 수 있는 다양한 AI•머신러닝 툴들이 쏟아져 나오고 있습니다. 기본적인 머신러닝 기법들을 담고 있는 scikit-learn을 시작으로 deep learning이 화두가 되며 구글에서 내놓은 tensorflow까지 다양한 회사, 연구원이 오픈소스 트렌드에 맞춰 수많은 머신러닝 라이브러리를 공개하고 있습니다. 이러한 라이브러리들은 기존의 프로그래밍 언어를 이용하여 효율적으로 계산될 수 있도록 개발, 패키징 되어 보다 손쉽게 머신러닝을 체험해볼 수 있습니다. 최근에는 기존 프로그래밍 언어로 개발된 머신러닝 라이브러리를 넘어서 머신러닝 기법에 특화된 확률론적 프로그래밍 언어(Probabilistic Programming)들이 개발되고 있습니다. 이는 기존 하드웨어에서 머신러닝 계산에 적합한 GPU 하드웨어의 폭발적인 인기를 넘어서 인공지능에 최적화된 하드웨어(Google Tensor Processing Unit) 개발 시도가 소프트웨어에서도 일어나고 있다고 생각합니다. 백문이 불여일견이니만큼 엘리스에서 간략한 소개 튜토리얼을 해보실 수 있습니다.구글 Tensor Processing Unit (TPU)확률론적 프로그래밍 언어란?확률론적 프로그래밍 언어는 머신러닝 분야, 확률과 통계 분야, 그리고 프로그래밍 언어 분야, 총 세 분야를 아울러 만들어진 새로운 프로그래밍 언어입니다. 기존의 전산학(Computer Science)은 주어진 변수/파라미터가 있고, 이를 프로그램 및 계산하여 결과 값을 얻습니다. 머신러닝 내에서 주로 쓰이는 방법은 추론인데 이는 관측되는 결과 값 들이 있고, 이를 다양한 수학적 방식으로 추론하여 변수/파라미터값들을 구합니다. 따라서 확률 통계의 수학적 계산법을 직관적으로 프로그래밍 할 수 있기 위해선 기존의 전산학 방식이 아닌 새로운 방식의 프로그래밍 언어가 필요하고, 확률론적 프로그래밍 언어는 이러한 패러다임에 맞춘 시도라고 볼 수 있습니다. 이렇게 개발된 언어는 복잡한 머신러닝 기법도 간략한 코드로 개발할 수 있게 하는 목표를 가지고 있습니다.확률론적 프로그래밍 언어란? (NIPS Tutorial 2015)확률론적 프로그래밍 언어 리스트 (Wikipedia)우리에게 아직은 생소해 보이는 확률론적 프로그래밍 언어는 현재 활발히 연구되고 있으며, 그 종류도 30가지가 넘습니다. 각 확률론적 언어는 기존의 다양한 프로그래밍 언어에서 파생 되었는데요, 엘리스에서 사용하는 주 언어 중 하나인 Python을 기반으로 한 PyMC3을 기반으로 튜토리얼을 만들었습니다.그 외 실제 실험에서 적용된 Picture라는 확률론적 프로그래밍 언어는 2D 얼굴 사진을 토대로 3D 얼굴을 모델하는 프로그램을 단 코드 50줄로 만들어 2015년에 공개되었습니다. 이를 보통 프로그래밍 언어로 개발했다면, 몇 천줄로 개발되어야 했다고 합니다.마치며이번 글에서는 간략하게 확률적인 프로그래밍 언어를 소개했습니다. 아직은 생소할 수 있지만, 점점 다양한 분야에서 머신러닝이 사용 될 수록 이에 적합한 확률론적 프로그래밍 언어의 연구, 개발은 활발해 질 것으로 예상됩니다. 지금 엘리스에 로그인 하셔서 확률론적 프로그래밍 언어 실습 예제를 실행해보세요!엘리스에 올려진 실습문제를 실행하면 책에서만 보던 이런 그래프들이 무슨 의미인지 이해하고 실제로 그려볼 수 있습니다!글쓴이김재원: The Lead, Elice김수인: KAIST 전산학부 박사과정박정국: KAIST 전산학부 박사과정#엘리스 #코딩교육 #교육기업 #기업문화 #조직문화 #서비스소개

기업문화 엿볼 때, 더팀스

로그인

/