스토리 홈

인터뷰

피드

뉴스

조회수 2809

리디북스 웹뷰어의 이어보기를 개발하며

최근 리디북스에서는 판타지 연재물을 웹에서 바로 볼 수 있는 기능을 새롭게 선보였습니다.기존에는 별도의 앱을 설치하고 다운로드하는 과정을 거쳐야 했기에 연재물을 보는 사용성이 좋지 않았습니다만, 브라우저에서 바로 볼 수 있는 “웹뷰어” 기능을 제공함으로써 사용성을 높일 수 있었습니다.그리고 여기에 사용성을 더하기 위해 추가된 것이 이어보기 기능입니다. 짧아도 100화 이상, 길게는 1000화가 넘는 연재물에서 다음 화로의 매끄러운 연결은 매우 중요합니다. 혹은 잠시 읽기를 중단했다가 다시 돌아왔을 때, 어디까지 보고 있었는지를 빠르게 알려준다면 호흡을 이어서 작품에 더욱 몰입할 수 있을 것입니다.이어보기가 구현된 모습리디북스에 로그인되어 있다면, 이곳에서 확인하실 수 있습니다.이번 글은 이어보기 기능에 대한 개발 후기입니다. 요구 사항에 따라 여러 저장소 솔루션을 비교해 보았으며 최종적으로 Couchbase를 선택한 이유와 간단한 벤치마크 결과, 그리고 겪었던 문제를 공유합니다.요구 사항기획된 내용을 요약하니 아래와 같습니다.연재물의 가장 마지막에 읽은 화를 알 수 있다.보았던 모든 연재물에서 가장 마지막에 읽은 연재물을 알 수 있다.사용자가 본 모든 연재물 목록을 확인할 수 있다.이를 개발자 용어로 다시 풀어보면 아래와 같습니다.연재물을 읽을 때마다 연재물 ID와 화(episode) 정보를 기록한다.보았던 연재물을 최신순으로 정렬하여 가져온다.선택된 연재물의 마지막으로 읽은 화를 가져온다.목록에서 특정 연재물을 삭제한다.이어보기는 가장 마지막에 읽은 연재물을 기억하기 위해 작품을 열 때마다 해당 정보를 기록해야 합니다. 그런데 수십 화를 연달아서 보는 연재물의 특성상 내가 어디까지 읽었는지를 조회하는 것(read)보다 내가 읽은 연재물을 기록하는 것(write)이 더 많을 것으로 판단했습니다. 즉, 읽기보다 쓰기가 더 많을 것으로 예상했습니다.NoSQL을 쓰자대부분의 연산이 쓰기(write)와 관련된 이상, 어떤 저장공간을 사용할 것인지가 주된 관심사였습니다.특히 RDBMS와 NoSQL 사이에서 어떤 것을 사용할지 많은 고민과 테스트를 했고, 결국 아래와 같은 이유로 NoSQL을 사용하는 것이 적합하다고 판단했습니다.현재 사용 중인 MariaDB를 그대로 사용한다면 마스터에 부담을 줄 수 있다.별도로 MariaDB를 구성하더라도 운영 및 쓰기 분산하기가 여전히 어렵다.반면 NoSQL은 RDBMS 대비 확장(Scale out)이 간편하므로 운영에 대한 부담이 적다.단순 Key-Value 보관 용도면 충분하다.이어보기 데이터는 독립적인 성격을 가지고 있어서 다른 사용자 데이터와 JOIN을 할 필요가 없다.이어보기 데이터는 크리티컬한 트랜잭션이 필요하지 않다.MongoDB vs. Couchbase데이터를 영속적으로 유지해야 한다는 요구 사항을 충족하기 위해, Redis 등의 메모리만 사용하는 NoSQL은 제외했습니다. 물론 디스크에 기록할 수 있지만, 성능이 급감하기 때문에 실용적이지 못 합니다. 또한, 메모리 사이즈에 기반을 두기 때문에 Scale up 비용이 크고, 서비스 확장시 Scale out 빈도가 높습니다.그래서 MongoDB와 Couchbase를 비교 대상으로 했습니다. 둘 다 도큐먼트 기반의 NoSQL이고 확장이 용이합니다. 과거에는 MongoDB가 Write lock 사용에 있어서 문제점이 있었지만, 최근 버전에서는 문제가 되지 않습니다.[1] 둘 다 기업용 서비스 및 충분한 부가 기능들을 제공하므로 선택하기 어려웠지만, 최종적으로 아래와 같은 이유로 Couchbase(CE)를 선택했습니다.1. 이미 사내에서 다른 서비스에 사용되고 있습니다.가장 중요한 요인이었습니다. 더 좋은 솔루션이 있더라도 어디까지나 서버 스택을 늘리는 것 이상의 효용이 있는지를 따져보아야 합니다. 이미 사용하고 있는 솔루션이 있다면, 검증이 되었을 뿐만 아니라 개발 및 운영 경험도 활용할 수 있습니다.2. 이어보기는 복잡한 쿼리(Query)가 필요 없습니다.이어보기에서 사용할 쿼리는 간단하기 때문에 Couchbase의 뷰(View)만으로 충분했습니다.Couchbase, 실제 성능은 어떨까?테스트를 하기 전 우리가 어떤 식으로 사용할 것인지 정리해야 합니다. 애플리케이션 액세스 패턴이나 동시성 문제, 데이터 구조화 등을 파악하고 그에 맞는 테스트를 진행해야 합니다. 이번 이어보기는 쓰기 연산이 보다 많기 때문에 이로 인한 뷰의 인덱싱(Indexing)에 초점을 맞추고 테스트를 진행했습니다.성능을 위협하는 요소들View IndexingCouchbase는 MapReduce를 이용하여 뷰를 제공합니다. MapReduce는 일반적으로 리소스를 많이 소모하는 동작입니다. 그래서 Couchbase는 버킷의 새로 갱신된 데이터만 인덱싱하는 Incremental MapReduce라는 기법을 적용해서 리소스 소모를 줄였다고 합니다.[2] 하지만 해당 작업으로 인한 부하는 여전히 발생합니다.Auto CompactionCouchbase는 데이터와 인덱스를 디스크에 데이터를 저장할 때 파일에 추가하기(Append) 모드로만 쓰기를 수행합니다.[3] 그리고 오래되고 불필요한 데이터들은 추후 한꺼번에 정리하는데, 이는 디스크 쓰기 성능을 최대화하기 위함입니다.그런데 이렇게 추가만 하게 되면 오래된 정보들은 파일의 앞에 쌓이게 됩니다. 그리고 사용하지 않게 된 데이터도 남아있습니다. 이를 주기적으로 정리해서 최적화하는 작업을 Auto Compaction이라고 합니다. 뷰의 인덱스는 디스크에 존재하기 때문에 디스크 작업이 있으면 인덱싱에 영향을 미치게 됩니다.성능 테스트Couchbase는 기본적으로 5,000ms마다 Index를 업데이트합니다.[2] 그리고 데이터를 비동기적으로 응답합니다. 비동기는 응답속도를 빠르게 하지만, 데이터 불일치가 발생할 수 있습니다. 데이터 불일치가 신경 쓰이고 이 시간이 길다고 생각되면, stale 옵션을 지정해서 뷰의 인덱스를 업데이트할 수 있습니다.이어보기는 뷰가 간단하기 때문에 응답시간에 큰 문제가 없을 것으로 예상하고 stale 옵션을 꺼두었습니다. 이 옵션은 뷰를 조회했을 때 버킷의 변경사항에 따라 뷰를 인덱싱하고 데이터를 응답합니다. 하지만 예상한 것과 같이 실제로도 응답시간이 짧은지 확인할 필요가 있습니다. 그래서 다음과 같이 테스트를 진행했습니다.테스트 환경은 아래와 같이 2-tier로 준비하고 요청을 늘려가면서 RPS를 측정했습니다.서버 구성OS: Ubuntu 14.04Application: Couchbase Server (CE) 3.1.3클라이언트 구성클라이언트 1개에서 50개의 세션으로 요청10만 사용자 가정책은 1만개의 책중 랜덤으로 선택됨요청의 70%는 책 읽기(Bucket Write)요청의 30%는 연재물의 마지막에 읽은 책 가져오기(View Read)그래프 분석성능 테스트 주요 지표RPS : Response Per SecondSP : Saturation PointBuckle zone : 시스템 과부하로 인해 내부 자원이 서로 경쟁상태나 적체 상태가 심해지기 때문에 최대 처리량보다 더 떨어지는 경우가 발생함성능테스트 결과그래프를 보면 요청이 늘어남에 따라 RPS가 선형으로 증가하지만, SP인 8,000 RPS에 도달하고 나서 Buckle zone에서 7,000 RPS로 수렴하고 있습니다. 물론 1개의 클라이언트에서 세션을 생성해서 테스트를 진행했기 때문에 서버의 성능 부족이 아닌 클라이언트의 병목 현상이 원인일 수 있습니다. 또한 JMeter나 다른 부하 테스트 툴을 사용하지 않고 간략하게 만든 테스트 툴을 사용하였기 때문에 수치가 부정확할 수 있습니다. 그러나 어디에서 병목이 있었든 현재 이 이상의 성능이 필요하지 않기 때문에 테스트 결과에 만족할 수 있었습니다.이어보기 배포 후모바일 브라우저 캐시 문제이어보기 기능을 배포하자마자 당일 저녁 이슈 하나를 접수했습니다. 아이패드와 PC를 번갈아 이용할 경우 이어보기 데이터가 맞지 않다는 것이었습니다.데이터를 쌓을 때 모든 이력을 기록하지는 않았지만, 다행히도 Couchbase에 이용기기와 시간은 기록하였기 때문에 이를 바탕으로 디버깅을 할 수 있었습니다. (서비스 초기라 할지라도 최대한 많은 이력을 남기는 것이 중요함을 다시 느꼈습니다)원인은 아이패드의 멀티태스킹으로 인한 캐시 소멸이었습니다. 아이패드 브라우저의 캐시가 소멸되면서 마지막으로 열어두었던 페이지가 강제적으로 리로딩되었고, 이때 의도치 않게 마지막 위치 정보가 덮어씌워진 것입니다.이 문제는 기술적으로 해결이 쉽지 않아 결국 기획을 수정하게 되었습니다. 사용자가 해당 책을 읽었다고 판단하는 기준이 “페이지를 열어본 즉시”였다면, 이를 “페이지를 열고 수 초 이상을 유지”하는 것으로 기준을 변경하였습니다. 물론 근본적인 해결책은 아니었지만, 실제 사용에는 지장이 없는 합리적인 해결책이라고 생각합니다.Key 구조의 변경 및 동시성 문제Couchbase는 높은 성능을 위해 메타데이터(Key + @)를 모두 메모리에 적재하는 특징이 있어서, Document 하나가 평균 350Byte를 차지하고 있었습니다. 따라서 현재 상태로 1000만개의 데이터를 저장할 경우 최소 3.5G의 메모리를, 2개의 사본(Replica)를 유지할 경우 약 10.5G의 메모리를 사용하게 될 것으로 예상되었고 이는 큰 부담으로 다가왔습니다.처음에는 단순히 “사용자ID_연재물ID” 형태의 Key를 사용하였지만, 보다 빠르게 증가할 것으로 예상되는 것은 사용자보다 연재물 이었으므로 아래와 같이 Key값을 변경하여 메모리 사용량을 크게 줄였습니다.// U_id : S_id 조합을 사용하면 Key가 엄청 많아진다. // 그래서 사용자당 Key를 100개로 제한하도록 한다. Count = 100 Key = '사용자ID' + ('연재물ID' % Count) 그런데 이렇게 Key 구조를 변경하였더니, 간단한 업데이트 동작임에도 불구하고 정상적으로 수행되지 않는 경우가 빈번하게 발생하였습니다. 이유는 낙관적 동시성(Optimistic concurrency) 모델의 특징 때문이었는데, Couchbase는 명시적인 잠금 이외에도 “Check and Set(CAS)”이라는 기능을 제공하고 있었습니다.공식 문서의 예제를 참고하여 아래와 같이 로직을 수정한 뒤로는 다행히도 동시성 문제가 아직까지 발생하지 않고 있습니다.boolean updateUsingCas(key, value) {  for (tryCount = 0; tryCount < MAX>    orgValue, cas = getValueAndCas(key)           // Update the original value.     // newValue = ... if setValueWithCas(key, newValue, cas)      return SUCCESS sleep(0.1) // 부하를 줄이기 위해  }  return FAIL } 맺으며동작하는 서비스에 새로운 기능을 추가한다는 것은 어려운 일입니다. 특히 새로운 데이터 스토리지를 필요로 하는 일이라면 더더욱 어렵다고 생각합니다. 그리고 그럴 때일수록 설계에 많은 시간을 들여야 한다는 것을 느꼈습니다. 설계 초기에는 RDBMS의 샤딩까지 고려하였지만, 요구 사항을 구체화할수록 단순 Key-Value로도 같은 문제를 해결할 수 있음을 깨달았기 때문입니다.또한, 서비스 개발에 있어서 어려운 문제를 마주했을 때 기술적으로만 접근할 것이 아니라 고객이 정말 원하는 것이 무엇인지를 고민하여 기획적으로 해결하는 능력도 중요하다는 것을 실감하였습니다.마지막으로 Couchbase는 현재로서도 꽤 좋고 앞으로도 많은 발전이 기대되는 NoSQL입니다. 도입을 고민하시던 분들께 조금이라도 도움이 되었기를 바랍니다.참고자료[1] MongoDB - Concurrency[2] Couchbase - Views Operations[3] Couchbase - File write#리디북스 #개발 #개발자 #서버개발 #서비스개발 #고객중심 #기능개발 #Couchbase #인사이트 #개발후기
조회수 370

금요일의 해커톤

안녕하세요. 엘리스입니다!지난 8월 말, 엘리스의 야심 찬 첫 해커톤이 있었습니다. 이번 해커톤은 매주 금요일 찾아가는 문제 ‘금요일에 코딩하는 토끼’에 대한 수강생 여러분의 성원에 힘입어 개최되었습니다.주제는 ‘코딩 문제의 A에서부터 Z까지 직접 설계하고 제작한다.’ 해커톤에서는 아이데이션 단계에서부터 문제 기획과 코딩, 채점을 위한 그레이더 제작까지 코딩 문제의 모든 것을 다루었습니다. 물론 실제 문제 동작을 위해 실행과 채점을 반복하며 디버깅하여 완벽한 실습 문제를 만드는 것 역시 이번 경연의 핵심이었는데요.이를 통해 모든 참가자 여러분들은 일일 엘리스 아카데미 실습 문제의 출제자가 되었습니다. 어떤 과정을 거친 어떤 결과물들이 있었을까요?해커톤 현장 스케치해커톤의 소개를 경청 중이신 참가자 여러분.지금까지 프로그래밍 문제를 많이 풀어보셨을 여러분이, 반대로 문제의 출제자가 되어 문제를 구성하는 관점에서 생각해보고 채점 방식까지 고민해본다면 프로그래밍에 대한 이해도를 더 높일 수 있을 것이라는 기대로 이와 같은 해커톤이 기획되었습니다. 교육자로서 엘리스 플랫폼의 다양한 기능을 직접 이용해볼 수 있는 것은 일석이조의 이점이었죠!경직된 분위기를 깨고 뇌를 말랑말랑하게 만들기 위한 아이스 브레이킹 시간은 팀 대항전으로 진행되었습니다.간단한 코딩 문제를 가장 먼저 맞히는 팀이 점수를 얻는 스피드 코딩 게임을 통해서 순발력을 높이고, 잠시 후 해커톤에서 본격적으로 사용하게 될 엘리스 플랫폼과 친해질 시간도 가질 수 있었습니다.'그림 그리기 게임'에서는 각 팀 디자이너들의 창의력이 폭발! 개발과 관련된 온갖 단어들을 1초 만에 그림으로 표현해야 하는 설명자의 재치와 크로키 실력(?)이 강조되었던 순간이었는데요. 승자는 '오즈'팀! 모두 오즈 팀 디자이너의 그림 실력에 입을 다물지 못했다고 합니다.게임을 하는 동안 어느새 어색했던 처음의 분위기가 파괴되었습니다. ^^ 1시간 동안 문제의 초안을 기획하는 시간이 주어지고, 이어 각 팀의 아이디어 발표 시간이 있었습니다.해커톤의 룰은 아래와 같았는데요.실행 가능한 프로그래밍 문제 1개 출제.동화를 모티브로 한 문제 스토리를 기획.채점 가능한 그레이더 제작.모든 팀들이 알고리즘 문제를 기획해주셨습니다. 동화의 서사구조를 논리적으로 단순화하거나 변형하여 알고리즘 문제에 녹여낸 과정이 인상적이었습니다.아이데이션 단계에서는 문제의 완성된 모습이 전부 그려지지는 않았지만 많은 고민의 흔적과 창의적인 생각들을 엿볼 수 있어 이로부터 탄생될 프로그래밍 실습을 기대할 수 있었습니다.밤샘 코딩 중...우승 문제 소개기획하고 코딩하고 디자인을 하다 보니(!) 어느새 날이 밝아왔습니다. 이제 남은 것은 팀별 결과물 발표와 우승팀 시상 뿐!'금코토'를 패러디하여 팀 명을 지어주신 어린 왕자 팀. /* prince */로고까지 깨알 섬세!모든 팀이 각기 다방면에서 강점을 부각하는 문제를 출제해주셨기 때문에 우열을 가리기 어려웠는데요. ‘금코토’배 해커톤이라는 이름에 걸맞게 금코토 과목의 취지와 가장 부합하는 문제를 출제한 팀에게 가산점을 주어 우승팀을 선발하였습니다. 그 결과 대망의 우승 문제는...거울나라의 앨리스팀의 ‘케이크와 병’ 단순한 명료한 문제 구성과 초등학생도 이해할 수 있는 쉽고 친절한 프레젠테이션으로 인상 깊었던 문제였습니다. 완성도, 문제 활용도 면에서 금코토 문제를 능가하며 단순하면서도 재미있게 풀 수 있는 문제라는 심사위원들의 평가가 있었습니다. 우승팀인 거울나라의 앨리스 팀 전원에게는 엘리스 굿즈를 선물로 보내드립니다. :)이밖에 겁쟁이 사자를 동물의 왕으로 만들기 위해 용기의 성을 짓는 알고리즘 문제를 낸 오즈의 마법사 팀의 문제는 스토리에 착안하여 자칫 복잡해질 수 있는 내용을 세세한 문제 설계로 극복하려 했던 점이 우수하게 평가받았습니다. 술주정뱅이 별에 사는 만취한 아저씨를 옮기는 알고리즘 문제를 낸 ‘목요일에 코딩하는 어린 왕자’ 팀은 참신성과 '넓이 우선 탐색', '깊이 우선 탐색', '다익스트라 알고리즘'을 모두 공부해볼 수 있도록 한 문제 구성 면에서 높은 평을 받았습니다.큰 상품도 내걸지 않았던 첫 해커톤이었는데도 참가자분들 모두가 열과 성을 다해 밤을 새워 문제를 만들어 주셨습니다. 모든 참가자 여러분들께 감사의 말씀 전합니다. :) 해커톤 이후 진행한 설문 조사에서 100%의 확률로 모든 분들이 다음 해커톤에 재참가 의사를 밝히셨는데요. 모두 첫 해커톤을 즐겨주셨던 것 같네요. 엘리스에서는 앞으로도 해커톤을 지속적으로 개최할 예정입니다. 코끝 시려질 때쯤 더욱 풍성하고 유익한 기획의 해커톤으로 찾아뵐 예정이니 많은 관심 가져주세요!*금코토 — ‘금요일에 코딩하는 토끼’라는 엘리스 아카데미 과목의 줄임말. 매주 금요일 저녁때쯤 업로드되는 문제로, 특정 루트로 토끼가 움직이도록 코딩해야 하는 콘셉트와 귀여운 휴보 래빗이 특징입니다. >>문제 풀어보기(무료)
조회수 936

검은 머리 외국인으로서 스푼 라디오에 입사하기까지

스푼을 만드는 사람들 여섯 번째 이야기서비스 플랫폼 팀 막내이자 분위기를 담당을 맡고 있는, 6개월 차 개발자 Kyu를 소개하고자 한다.영어가 편해요? 아니면 한국어가 편해요?"일반적인 의사소통에 있어선 한국어가 편하고, 업무를 볼 땐 영어가 편해요."Q. 원래 되게 개구쟁이(?)의 이미지를 가지고 계신 줄 알았는데.."저 원래 진지한 거 진짜 싫어해요. 제가 겉보기엔 늘 장난꾸러기 같아 보이실 수도 있지만, 사실 이렇게 단 둘이 이야기를 하면 또 다른 진지하고 진정성 있는 저의 모습이 보이실 거예요. 저 지금 많이 진지해요?"(인터뷰 전에는 큐가 그저 재미있는 사람이라고 생각했는데, 인터뷰를 하고 나서 그를 다시 보았습니다..)'Kyu'라는 사람을 알고 싶습니다.Q. 본인은 어떤 사람이라고 생각하세요?Me, Myself, and I - "저는 제가 느끼는 것 그리고 원하는 것에 굉장히 집중을 하는 편이에요.제 본인 스스로에게 집중하는 양도 기준치도 꽤나 높은 편이에요. 무엇보다 스스로 혼자만의 시간을 굉장히 중요시합니다."Q. 국적이 Canadian이라 들었습니다. "네, 저는 8살 때 부모님과 함께 교육을 위해서 캐나다로 이민을 갔었어요. 그리고 캐나다에서 고등학교까지 있었고 그 후엔 미국에서 대학을 졸업했어요. 졸업 후에 한국에 취업을 하게 되어서 어느덧 한국 생활이 1년 3개월 차가 되어가고 있네요."Q. 한국에서 취업을 하게 된 계기가 있다면?"사실 처음에 제가 스타트업에 취업을 한다고 했었을 때, 주변에서 안정적인 곳이 아닌 스타트업을 선택하느냐라고 많이들 물어보셨어요. 그것도 한국에서요. 근데 저는 제가 정말 무슨 일을 하고 싶은지 잘 몰랐었어요. 목표의식과 노력 없이 공부를 하다 보니, 어느덧 졸업이 다가왔고 좌절하게 됐었어요. 정말 오랜 시간 아무것도 못했었어요. 길을 잃었다고 할까요? 그러다가, 용기를 내서 현실적으로 내가 할 수 있는 일이 무엇일까 고민 끝에 한국을 선택했어요. 한국엔 유능한 사람들이 정말 많고, 실력 있는 사람들이 열심히도 하는 곳이에요. 정말 무언가를 최선을 다해서 해본 다는 게 무엇인지 겪기 위해선 한국에서 배워보는 게 좋다고 생각했고, 실제로도 그렇다는 걸 느끼고 있어요."당신의 회사생활이 궁금합니다Q. 서비스 플랫폼 팀(서버팀)에서 하고 계신 업무는?"저는 현재 하고 있는 업무는, 정확히 말하자면 로그 데이터 수집 및 스푼 앱 내에서 발생하는 유저들의 행동 그리고 현상에 대한 데이터를 실시간으로 수집하고 조회합니다. 그리고 시간에 흐름에 따른 서비스 상태를 나타내 주는 작업을 하고 있습니다."Q. 현재 업무의 만족도는 어느 정도인가요?"업무에 대한 만족도는 높습니다. 저는 신입이고, 기본 역량이 팀원들에 비해서는 낮지만 제가 입사한 후 처음 시도한 것이 '로그 데이터 수집'인데요. 처음부터 끝까지 독립 시스템을 맡고 있다는 점이 굉장히 뿌듯합니다. 저를 그만큼 믿어주시기에 가능한 일이라고 생각합니다. 그렇다 보니 주인의식을 가지게 되고요. 앞으로 조금 더 만족도를 높이고자 한다면, 팀원들과 프로젝트를 도 함께 진행해보고 싶습니다."Q. 스푼 라디오가 큐의 첫 직장인 가요?"네, 정사원으로는 첫 직장이지만 그 전에는 인턴을 잠시 했었어요. 이건 제가 한국에서 겪은 좋지 않은 기억이지만, 인턴 생활 때, 타 스타트업에서 3개월 정도를 일을 했었는데, 임금 체불 문제가 있었어요. 당연한 부분이자 저의 권리가 지켜지지 않는 것을 보고, 다시 캐나다에 가고 싶단 생각을 했었어요. 그때 자존감도 많이 낮아지고 참 암울했던 시기였어요."Q. 한국 회사에서 느끼는 문화 차이가 있나요?"사실 제가 생각했던 것보다 워라벨이 잘 지켜지고 있어서 그 부분은 의외라고 생각이 들었어요.다만, 사람들과 함께 편하게 이야기를 하는 과정에서 문화적 차이를 느끼곤 해요. 예를 들면 Gender 부분 이라던지 등등. 의식이 조금 다르다고 느낄 때가 있어요. 하지만 한국 문화라던지, 의식의 차이를 저도 받아들이고 많이 노력하고 있어요. 누구나 의견과 관점은 다를 수 있으니까요. 잘 못되었다기 보단, 다른 사람들이구나 하고 받아들이려고 합니다."Q. 회사에서 가깝게 지내는 동료는 누구인가요?"업무를 가장 많이 함께 해서 가까운 분은 찰스, 개인적으로 제일 친하다고 느끼는 분은 샘입니다. 왜 친하다고 느끼는지는 모르겠지만 저도 모르게 자꾸 관심이 가요. 빨리 더 친해지고 싶은 생각도 들고, 그저 좋은 분이라고 느껴서입니다." (하지만 그분의 마음은 저도 몰라요.. 저만 친하다고 느낄 수도?)커피를 좋아하는 Kyu 당신의 사생활이 궁금합니다Q. 언제 가장 캐나다가 그립다거나 가고 싶어요?"일단, 미세먼지 많은 날이요.  그리고, 가끔씩 이런 마음이 들 때가 있어요. 한국에서는 쳇바퀴도는 매일 똑같은 삶을 사는 것 같다는 느낌(?) 한국에서는 아무것도 하지 않아도, 뭔가 늘 바쁜 그런 느낌이 들어요. 안정감이 없다고 해야 할까요? 한국은 소비를 통해서 스트레스를 해소하는 나라인 거 같아요. 주로 뭘 사 먹거나, 소유하거나. 근데 캐나다에서 랑 미국에선 다른 방식으로 스트레스를 풀 수 있었거든요. 공감하시려는지 모르겠어요. 저는 그렇답니다. 한국에 살다 보니 이제는 사실 오히려 이제는 외국에 나가 산다는 게 더 큰 도전이 된 느낌이기도 하고요."Q. 가장 좋아하는 캐나다 음식은?"캐나다 초밥요! 캘리포니아 롤이 캐나다 밴쿠버에서 만들어졌단 사실 알고 계시나요? 저 그거 정말 좋아합니다.."Q. 스스로를 어느 나라 사람이라고 생각하나요?"저는 국적은 캐나다이지만, 저의 정체성은 한국에서 시작되었고, 한 번도 그걸 잊은 적이 없어요. 캐나다에서도 한국 문화에 대한 관심을 늘 가지고 있었거든요. 예능이라던지, 시트콤 다 따라서 봤었으니까요. (원래 외국에 살면 더 한국 프로그램 많이 보게 된다는..) 아무쪼록, 저는 제가 한국인임을 잊어 본 적이 없어요. 비록 국적은 캐나다인이지만요. 그리고 저는 최대한 한국의 가십거리를 말하지 않아요. 왜냐면, 저는 이곳에 오래 살지 않았고 제가 기여할 수 있는 부분이 굉장히 제한적이거든요. 제가 국방의 의무를 했다거나, 투표권이 있으면 모를까 제가 감히 함부로 한국에 대해서 말하고 싶지 않아요. 무엇보다 저는 제 스스로가 어느 국가의 사람인 지보단 '나'라는 스스로에 집중하는 편이에요."(앞으로 외국인이라고 부르지 않을게요 큐..)Q. 다른 이루고 싶은 꿈이 있다면?"다음 생에 저는 래퍼가 되고 싶어요. 정말로 진지하게, 힙합과 랩이라는 문화를 존중하고 좋아합니다. 그저 취미로 시작하고 싶은 게 아니라,  정말 다시 태어나면 온전히 랩에 집중해서 좋은 래퍼가 되고 싶어요."Q. 어떤 사람과 함께 일하고 싶나요?개발자로서 이루고 싶은 비전이 확실한 사람이요. 무엇보다 소통하는 데 있어서 나이를 떠나, 마음이 열려있는 사람과 함께 일하고 싶습니다. 서로를 존중할 수 있는 그런 사람이요.탁구를 좋아하는 KyuQ. 마지막으로 하고 싶은 말이 있다면?"주변 친구들이 스푼에서 일을 시작하기 전과 후가 많이 바뀌었다고 말하는데, 저는 제 스스로에게 정말 많은 변화가 생겼다고 생각해요. 조금 더 진지하고 진중한 사람이 된 것 같고 이 긍정의 변화가 앞으로도 계속되길 바랍니다. 아! 그리고 회사에 제공되는 샐러드가 매일 아침마다 오면 좋겠어요. 저 그럼 정말 회사 지금보다 더 즐겁게 다닐 수 있습니다"P.S: 매번 다른 사람들의 인터뷰를 하고 계신 Sunny를 제가 직접 인터뷰해보고 싶어요.서비스 플랫폼팀 팀원들이 Kyu를 한마디로 표현한다면?Charles 曰:  '대장' - 대시보드 장인Sam 曰:  '거머리' - 자꾸 달라붙어서..Mark 曰: '감초 같은 사람' - 약방의 감초처럼 저희 팀 업무 전반에 없어선 안될 사람(큐가 이렇게 하라고 시켰어요) 
조회수 43220

프론트엔드 개발자(Front-End Developer)에 대해 알려드립니다!!

안녕하세요 크몽 개발팀입니다. 오늘은 일상적인 'IT 이야기'가 아닌 제가 맡고 있는 직책인'프론트엔드 개발자(Front-End Developer)'에 대해 포스팅을 해보고자 합니다.여러분들은 혹시 'Front End'라는 용어에 대해 알고 있으신가요? 저도 제일 처음 이 단어를 들었을땐 이게 대체 무슨 단어인가 했습니다.이 용어 외에도 'Back End'라는 단어도 있는데요, 물론 처음만나는 단어가 두개인만큼 두배로 어려워보일 수 있겠지만.. 놀라셨을 가슴 한번 쓸어내려드리고 전~혀 어렵지않다는 것을 차차 설명해드리겠습니다.----------------------------------------------------------------------------------------'프론트엔드'란??우선, 'Front End'라는 단어는 어떤의미의 단어일까요? 'W사'의 사전을 통해 알아보겠습니다.   한마디로 말씀드려서 '프론트엔드'는 사용자들에게 보이는 영역을 책임을 지는 것이며 '백엔드'는 시스템적인것으로 눈으로 보이지는 않지만 말 그대로 뒤에서 전산 처리를 하는 것을 말합니다.즉, '프론트엔드'는 시스템적으로 멋지게 만들어진 아이맥의 내부를 감싸는 껍데기를소비자들이 사고 싶게 만드는 디자인으로 구현하는 작업을 말하는 것입니다.크몽의 '조너선 아이브'같은 존재(?)라고 말씀드릴 수가 있겠군요.. 하하하하 (자뻑 죄송합니다(__);;)  '프론트엔드 개발자'의 목표는?'프론트엔드 개발자'의 미션은 두가지라고 말씀드릴 수가 있습니다.    첫번째로, 사용자들이 홈페이지를 친숙하고, 직접적으로 보여지도록 개발하는 것인데 딱 두가지!! 개발스킬과 미적감각을 동반하여야 합니다.여기서 중요한점은!! 쿤이는 디자인을 좋아라하지만 영감이 떠올릴만한 미술관과는 거리가 있다는 점점점점점점...앞으로 열심히 다녀보겠습니다!다시 본문으로 돌아가서..두번째는, 끊임없이 변화하는 웹세상에서 어떤툴과 테크닉을 썼는지 알고 있어야 한다는 점입니다.이 부분은 변화를 사랑하는 쿤이에겐 식은죽 먹기보다 쉽다고 하는게 맞겠네요!! (제발 그렇다고 해줘요..ㅠㅠ) '프론트엔드 개발자'가 쓰는 툴은?'프론트엔드 개발자'가 쓰는 툴의 몇몇은 웹사이트의 UI를 개발하는 툴에서 구할 수 있습니다. 첫번째로, 'HyperText Markup language'라고 불리는 'HTML' 되겠습니다.이 마크업언어는 어떤 웹사이트에서 중추적인 역활을 하는 그런 녀석입니다. 이 녀석은 말이죠... 자신의 이름을 문서의 앞뒤에 안써주면 자신의 정체도 모르는 그런녀석이구요,이 녀석의 명령어(태그)를 쓸땐 말이죠 명령어 끝에 닫는태그를 안해주면 크게는 문서 전체를 뒤죽박죽으로 만드는 그런 녀석이에요.어떨때는 파트너('CSS')와 함께 어디 놀러갈땐 각 장소(인터넷 익스플로어, 크롬 등..)에 따라 다른 매력을 발산해줘서 양파같이 까도까도 속을 모르는 그런 녀석이에요.두번째는, 'Cascading Style Sheet'라고 불리는 'CSS'입니다이 스타일 시트는 프레젠테이션효과를 주며 우리의 웹사이트가 단 하나밖에 없다는 희귀성을 부여할 수 있습니다. 이 녀석은 아까 말씀드렸듯이 'HTML'의 파트너에요. 남자는 여자하기 나름이란 말과 같이 'HTML'은 'CSS'하기 나름이라고 말씀드릴수가 있을 것같네요. 직접적으로 말씀드리자면 'HTML'이 몸이라고 보시면 'CSS'는 옷입니다. 'CSS'가 어떻게 스타일을 주는가에 따라서 웹사이트가 최신스타일룩을 보여줄 수도 있으며 잘못 쓴다면 90's 힙! to the 합!스타일을 보여 줄 수도 있습니다. 그래서 많은 사이트들이 사용자들에게 직접적으로 보여지는 스타일에 대해 신경쓰는 것이 이러한 이유라고 말씀드릴 수가 있습니다.세번째는, 'Content Management System'인 'CMS'입니다우리 한글로 표현하자면 내용관리시스템이란 것인데 아마 생소하실 것이라고 생각 듭니다. (실은 저도 생소했습니다ㅎㅎ)이 녀석은 한마디로 웹 사이트의 내용을 관리하는 시스템인데요.내용 관리 애플리케이션('CMA')과 내용 배포 애플리케이션('CDA')이 있는데요,그냥 약자로만 봤을 때엔 저기 아무 증권사나가서 한번쯤은 가입해야 될 것같은 분위기죠? 단호하게.. 아닙니다!! 연이자 2%할 것같은 'CMA'가 하는 일은 'HTML'에 들어갈 내용, 변경, 제거 등의 관리 프로그램이고,왠지 아이들의 미래를 위해 들어야될 것같은 'CDA'는 웹 사이트의 모든 수치(현행화)를 보고 편집할 수 있는 정보편집 프로그램입니다.우리가 흔히 볼 수 있는 형태로는 웹 기반 편찬(마법사템플릿 등), 형식 관리, 계정 제어, 데이터의 색인,테이터 탐색, 키워드 검색 등이 있을 수 있겠습니다.프론트엔드 개발자가 유의할 점은?프론트엔드개발자는 다음 두가지의 사항에 대해 유의해야 합니다.첫번째는, 접근성입니다. 앞서 말씀드렸듯이 이용자들에게 친숙한 모습으로 다가가야합니다.한번도 보지도 듣지도 못한 그런 UI로 이용자들에게 다가간다면 과연 잘 사용할 수 있을지가 문제일 겁니다.그런 맥락에서 말씀드리자면 모든기기에서 항상 똑같은 모습으로 이용자들을 맞이한다면각 기기에서 최적화 되지못한 화면들이 나와 이용자들에게 혼란을 줄지도 모를 일입니다.그렇기때문에 동적인 사이트를 만들어야 된다는 생각을 프론트엔드 개발자는 생각하고 있어야합니다.두번째는, 사용 간편성입니다. 만약 접근성이 좋아졌다고 하더라도 검색엔진에 최적화되지않은 사이트라면전세계적 검색사이트인 G사에서 사이트안의 컨텐츠와 연관된 내용을 검색하더라도 상위에 랭크 안되는 경우가 많습니다.그렇게 된다면 검색사이트로 원하는 사이트를 찾아들어가는 지금으로는 많은 잠재이용자들의 유입을 막아 더 이상 서비스가 성장하지못하는 상황까지 갈 수 있습니다.---------------------------------------------------------------------------------------- 이렇게 제가 하는일에 대해 포스팅을 하다보니 제가 맡은 업무가 우리 크몽서비스에 얼마나 큰 영향을 주는지 알 수 있었는데요... 갑자기 제 어깨에 곰한마리가 앉은 것같은 느낌이 드네요ㅠㅠㅠㅠ (아~ 피로야가라~!!!) 지금까지 제가 공부한 내용들을 간략하게 포스팅해보았는데요.담번엔 배운것들을 쓰는 과정을 시간이 허락한다면 보여줄 수 있는 포스팅으로 찾아 뵙겠습니다. :)#크몽 #개발자 #개발팀 #프론트엔드 #인사이트 #팀원소개
조회수 1013

[Buzzvil People] Ben Yoo, Software Developer

 Buzzvil People에서는 다양한 배경과 성격 그리고 생각을 지닌 버즈빌리언들을 한 분 한 분 소개하는 시간을 갖습니다. 어떻게 버즈빌에 최고의 동료들이 모여 최고의 팀을 만들어가고 있는 지 궁금하시다면, 색색깔 다양한 버즈빌리언들 한분 한분의 이야기가 궁금하시다면, Buzzvil People을 주목해주세요.1. 간단한 자기 소개 부탁드립니다.  안녕하세요 저는 버즈빌에서 Server engineering 을 맡고 있는 유병우입니다. 회사에서는 Ben 이라는 닉네임을 쓰고 있고 저와 아내 사이에 아기가 하나 있는데 회사에서는 벤, 벤처, 미니벤이렇게 부르고 있습니다. 성격은 매우 Active 해서 웬만한 스포츠는 다 좋아하고 회사에서는 Rock band도 하고 있습니다. 프로그래머! 어린 시절 Basic 이라는 언어로 시작한 프로그래밍이 너무 재밌기도 했고 가능한 많은 사람들에게 유익을 끼치고 싶다는 생각에 Software Engineer 가 되었습니다. 10년 전 병역특례 시절 카카오톡 이전에 존재했던 m&Talk 이라는 무료 메신저 개발을 시작으로 삼성의 Chat@n, 그리고 Line, Naver 외 여러 앱에 들어가는 push notification platform 을 개발한 경험이 있습니다. 전 세계에서 억 단위가 넘는 유저들에게 서비스하고 그 유저들에게 좋은 경험을 선사하는 것이 저에게 더욱 Software 의 매력에 빠지게 만들었던 것 같습니다. 새로운 기능이나 개선사항을 배포하고 나면 유저들의 Feedback 을 보는 것이 아침에 눈을 뜨면 가장 먼저 하는 일이었습니다. (늘 즐겁기만 한 건 아니었습니다. 특히 버그를 배포한 다음 날엔.. -_-a)  2. 어떻게 버즈빌에 오시게 되셨나요?  Infobank 에서의 인연 Infobank 에서의 병역특례를 하면서 m&Talk이라는 메신저를 개발할 때 Product Team의 Jay 는 iPhone 쪽 개발을 주도하고 있었고 저는 Android 쪽 개발을 주도하고 있었습니다. 함께 하나의 Product 을 만들면서 여러 가지 의견을 주고받기도 했고 서로 부족한 부분을 잘 보완해주는 친구이자 동료라는 생각을 많이 했습니다.  창업을 결심 나중에 Jay가 미국에서 함께 잠금화면 서비스를 만들어보자고 절 찾아왔고 그렇게 해서 Slidejoy 라는 회사를 함께 공동창업하게 되었습니다. 당시 좋은 회사에서 만족하며 생활하고 있었고 한 가정의 가장으로서 불안정한 길을 선택하는 것에 대한 두려움이 있었지만 좋은 사람들과 함께 창업이라는 기회는 자주 오지 않는다는 것과 다음의 단순한 생각이 창업의 길로 저를 이끌었습니다.  “뭐, 굶어 죽지는 않겠지.” 버즈빌로 합병 많은 위기들을 헤쳐나가며 Slidejoy 는 계속 성장했고 좋은 기회에 한국에서 비슷한 서비스를 하고 있던 저희보다 규모가 큰 회사인 버즈빌로 합병을 하게 되었습니다.  3. 버즈빌에서 어떤 업무를 담당하고 계신가요?  신기술 & Refactoring  제가 Software 를 개발하면서 가장 중요하게 생각하는 것은 효율 / 훌륭한 Design 을 가지고 있는 프로젝트 설계인데요, 효율을 올리기 위해 Go 와 Kubernetes 등의 기술을 회사에 도입했고 MVP, MVC 와 같은 Design pattern 들을 도입해서 코드를 읽기 쉽고 서로 분리하고 재사용 가능한 구조로 만드는 것에 노력 중입니다.    Go server engineering 실제 업무는 BuzzScreen / HoneyScreen 에서 광고 및 콘텐츠 할당과 Slidejoy 라는 서비스의 API 서버 개발을 맡고 있으며 Slidejoy 클라이언트를 개발했어서 클라이언트 쪽도 조금씩 참여하고 있습니다. 새로운 기술에 관심이 많다 보니 BuzzScreen 과 HoneyScreen 할당 로직을 전부 Go 언어로 포팅했고 비약적인 성능 향상이 있었습니다. (Go 서버 개발하기)  4. 스타트업에서 혹은 광고업계에서 일하는 느낌이 어떠세요?  사람 > 회사 대기업에서의 경험과 다르게 스타트업에서는 한 사람 한 사람이 일당백인 경우가 많은 것 같습니다. 그리고 그런 한 사람에 의해서 회사가 좌지우지 할 수 있는 곳이 스타트업입니다. 회사가 겪는 크고 작은 성장과 위기 모두 그대로 직원들에게 전달 되다 보니 그만큼 Buzzvil 식구들 모두 함께 만들어가는 서비스의 성공에 초점을 맞출 수 있습니다.  모바일 광고 저는 사실 미디어에 큰 흥미가 없고 광고는 더더욱 관심이 없었습니다. 하지만 Mobile 이라는 Big wave 안에서 0에서 출발해서 수억 명이 사용하게 된 급속도로 성장하는 Messenger 를 개발을 몸으로 체험할 수 있었고 모바일 광고 역시 Buzzvil 을 성장시킨 Big wave 였다고 생각합니다. 이렇게 급속도로 변하고 성장하는 시장에서 스타트업에 분명히 가치를 계산할 수 없는 엄청난 기회가 있다고 생각합니다.  5. 이것만큼은 버즈빌이 참 좋다! 어떤 게 있으실까요?  밝고 명랑한 문화 회사 회식 중에서 저는 “친해지길 바래” 라는 테마를 정말 좋아하는데요. 그야말로 정해진 예산 안에서 소수의 사람들끼리 마음껏 놀 수 있습니다. 지난번 친해지길 바래 때는 간단히 막국수 먹고 그 외의 모든 예산을 사격 및 방탈출 등의 액티비티에 쏟아부었습니다. 회식 날 밤에 배가 고픈 건 태어나서 처음이었던 것 같아요. 올해 초에 다녀왔던 전 직원들과 함께 다녀온 Bali 에서의 워크숍도 빠질 수 없습니다. 워낙 서로 친하게 지내다 보니 밤잠을 아껴가며 놀았던 기억이 납니다. 휴양지를 다녀왔는데 한국 돌아와서 1~2주 체력적으로 정말 힘들었던 기억이 나네요. 어느 Slack 채널에서나 난무하는 아재개그와 어처구니없는 3행시, 직원들의 표정이 담긴 얼굴로 만든 이모티콘 등 직원들 사이에서 주고받는 대화에는 늘 위트가 넘칩니다. 다크할거야! 라고 생각할 틈을 주지 않습니다. 비록 웃기지 않더라도 응원해줍니다. 노력은 언젠가 결실을 맺을 것이라 기대하기 때문이죠. 같이 놀고 같이 공부하는 회사 마음껏 교육이나 운동을 할 수 있도록 지원해주는 프로그램이나 무제한 도서구매를 지원하고 다양한 주제의 동아리나 스터디 모임 등이 있고 이걸 회사 차원에서 장려하는 것이 빼놓을 수 없는 Buzzvil 의 특징인 것 같습니다. 머신러닝, 영어스터디, 통기타 등의 스터디 모임과 밴드, 축구, 배드민턴, 테니스, 필라테스 등의 동아리 모임 등 대부분 직원들이 하나 이상의 프로그램에 참여하고 있습니다.  6. 개인적인 목표나 꿈이 있으신가요? 있다면, 버즈빌에서의 경험이 어떻게 도움이 된다고 생각하시나요?  많은 사람들에게 편리함을 제공 잠금화면이라는 대부분 사람들이 기존에 크게 활용되지 않고 있던 공간에 Value 를 만드는 것이 버즈빌에서 더 열심히 프로그램을 개발하게 만드는 원동력입니다. 위에도 기술 했지만 저는 가능한 많은 사람들에게 유익을 끼치고 싶어서 Programming 을 하게 되었고 대부분의 다른 산업과 달리 제가 하는 개발 작업은 하나의 복제품을 생성하는데 Ctrl+C / Ctrl+V 만으로 충분하니까 좋은 제품을 만들면 더욱 발전돼서 긍정적인 영향을 더 널리 끼칠 수 있을 것 같습니다.  다른 개발자들이 읽기 쉬운 코드 실제 제가 일을 하면 할수록 기존의 코드를 구조화하고 모듈화하고 사용하지 않는 코드를 지우는 일에 열심을 가지고 있다는 사실을 알게 되었어요. 확장이나 활용이 가능한 Core 나 Library 쪽 개발을 주로 하면서 어떻게 짜면 제 코드를 사용하는 사람이 덜 혼란스럽고 잘 활용할 수 있는지와 어느 곳에 어떤 설계가 어울리는지도 많이 고민해왔던 것 같습니다 버즈빌에서 버즈스크린이라는 상품을 통해서 저의 이런 성향을 마음껏 발휘하고 있습니다. 여러 Publisher 가 쉽게 사용할 수 있어야 하고 SDK 등을 사용할 때 쉽게 Integration 되어야 하기 때문이죠. ‘내가 짠 코드를 인수인계 받을 사람이 연쇄살인범이고 그 사람은 너의 주소를 알고 있다고 생각하고 코딩하라.’ 라는 말이 있는데요. 누구에게도 부끄럽지 않은 코드를 짜려고 항상 노력합니다. 갈 길이 아직 멀지만 연쇄살인범이라도, 어떻게 이렇게 코드를 (잘?) 설계했는지 의논하러 오게 만드는 것이 저의 꿈입니다.     *고성장 스타트업 버즈빌의 채용공고(전문연구요원 포함)를 확인하고 싶으면 아래 버튼을 눌러주세요!
조회수 7179

KT 채용 필수 정보! 실무자가 직접 말하는 KT 人사이드(IT 직무 편)

다가오는 하반기 공채 시즌에 앞서, 지난주 KT 직원들이 직접 말하는 KT 人사이드 ‘영업/마케팅’ 직무 편 잘 보셨나요? 자율적이고 수평적인 회사 분위기와 신입사원에게 주도적으로 역량을 펼칠 기회를 주는 KT의 기업문화를 간접적으로 접할 수 있었는데요. 알면 알수록 빠져드는 KT의 매력! 이번 주에도 더욱 빠져보시라고 새로운 인터뷰를 준비했습니다. KT 人사이드 영업/마케팅 직무 편 보러 가기 지난주에 이어 이번 주에는 KT 기술의 핵심! IT 직무를 맡고 계신 KT人들의 이야기를 들어보려고 합니다. 그들이 말하는 사람을 향한 KT의 기술! 지금. 들어갑니다.  “KT는 다양한 기술 분야를 융합한, 성장 가능성이 가장 큰 곳입니다.”- KT 기업사업컨설팅본부 IoT컨설팅팀 조아영 Q. 현재 어떤 직무를 담당하고 계신가요?A. IT 컨설팅이라는 직무를 맡고 있습니다. 제 직무는 기업 및 공공고객들에게 저희 KT 상품을 제안하는 일이며, 저는 그 중에서도 IoT컨설팅팀에서 일하고 있습니다. ‘IoT를 B2B에 어떻게 적용하느냐’라고 많이들 궁금해하시는데, 원격검침부터 차량, 통신까지 다양한 분야에 적용을 하고 있습니다. 신사업이니 만큼 정형화된 제안보다는 조금 더 사업을 주도적으로 진행하면서 컨설팅하는 재미가 있습니다. 그리고 ‘IT컨설팅’은 프로젝트 수주 전까지 제안서를 작성하고 컨설팅하는 직무가 주 업무이고, ‘IT수행’은 프로젝트 수주 이후에 협력사와 같이 프로젝트를 진행하는 것이 주 업무라고 할 수 있습니다. Q. KT를 선택한 이유는 무엇인가요?A. KT는 기존 사업인 통신기술(CT)뿐 아니라 정보기술(IT)까지 광대한 사업영역을 가지고 있습니다. 두 분야를 융합하여 확장할 가능성이 매우 크다고 생각해 선택하게 되었습니다. 특히 IT컨설팅을 지원한 이유는, 컴퓨터를 전공하며 습득한 이공계적 지식과 더불어 대학 신문사 활동을 통해 얻게 된 논리적 사고, 커뮤니케이션 능력을 함께 활용하여 역량을 발휘할 수 있을 것이라 생각했기 때문입니다. 현실적으로는 전공을 살리면서 광화문에서 근무할 수 있다는 점 또한 큰 장점으로 다가왔습니다.Q. 하루 일과를 설명해주세요.A. 일과는 근무장소에 따라 크게 두 가지 경우로 나뉩니다. 광화문에서는 주로 선제안이나 보고 등 일상적인 업무가 주를 이룹니다. 선제안을 위해서는 보통 타 부서와의 회의, 고객사 방문, 선제안서 작성 등을 합니다. 시장 조사, 실적 파악 등 내부 보고를 위한 보고서 작성 업무도 함께 진행되곤 합니다. 프로젝트에 투입이 되면 보안 상의 이유로 제안센터에 가게 됩니다. 보안이 철저한 제안센터에서 제안서를 작성하는데, PM(Project Manager)의 지휘 아래 각PL(Part Leader)들은 제안요청서에 맞게 담당한 부분을 작성해 나갑니다. 매일 유사하게 반복되는 업무보다 마감에 따라 업무강도에 강약이 있는 사이클식 업무를 선호한다면 컨설팅 직무에 적합하다고 생각합니다. Q. 지원자에게 마지막으로 전하고 싶은 취업 팁은?A. KT는 지원자들의 자소서를 모두 읽기로 유명한 기업입니다. 취업의 첫 시작인 자소서에 진심이 보인다면 아주 특별한 스펙이 없다 하더라도 가능성이 충분하다고 생각합니다. KT의 면접 분위기 또한 비교적 정중하다고 생각합니다. 면접관마다 다르겠지만, 입사 후에도 느낀 전반적인 회사의 분위기는 온화하다는 것입니다. 면접관들 모두 최대한 피면접자의 이야기를 들어주려고 노력하신다는 점을 기억해 주세요. 식상한 말이지만, 면접 때 너무 꾸며낸 모습을 보여주려고 하지 마세요. 자소서와 면대면 상황에서 일관되고 자연스러운 모습을 보여준다면 좋은 결과가 있을 것이라 생각합니다. 제 경험에 비추어 생각해보면, 말을 유창하게 잘하는 것도 중요하겠지만 내용이 논리적이고 일관되냐가 더 중요했던 것 같습니다.“KT인에게는 동료와의 커뮤니케이션이 가장 중요한 포인트입니다.”- kt skylife 기술본부 ICT운영팀 손형락Q. 현재 어떤 직무를 담당하고 계신가요?A. ICT운영팀에서 고객시스템 운영을 맡고 있습니다. 스카이라이프의 고객님들을 맞이하기 위한 고객정보관리시스템을 관리합니다. 고객님들을 유치할 때 필요한 시스템을 고객센터 및 파트너社에 최상의 품질로 제공하기 위해 노력합니다. 시시각각 변화하는 영업환경에 대응하면서, 시스템을 관리 해야 하기 때문에 중요한 업무라 생각합니다. Q. kt skylife를 선택한 이유는 무엇인가요?A. kt skylife는 국내 유일의 위성방송 사업자입니다. 유일하다는 것은 그만큼 시장에서의 경쟁력이 있다는 것을 의미합니다. 경쟁사에서 시도하지 못하는 기술을, 위성을 통해 우리만의 기술로 사용할 수 있을 것입니다. 하루가 다르게 변해가는 시장에서 유일하다는 것은 기업의 가장 중요한 매력 포인트라고 생각합니다.Q. 하루 일과를 설명해주세요.A. 9시 출근이나 항상 30분 일찍 도착합니다. 혹시 모를 장애에 대비하기 위한 습관이라고나 할까요. 퇴근 후에 온 메일이 있는지 확인하고, 그날의 업무를 정리합니다. 스케줄대로 움직이다 보면 어느새 6시. 오전∙오후 시간 모두 각 사업부서와 협의하기 위한 시간으로 사용하지만, 짬짬이 나는 시간들을 잘 활용하면 6시에 퇴근할 수 있습니다. 6시 이후에는 어학 공부 및 새로운 IT 트렌드를 접할 수 있는 각종 세미나에 다니며 틈틈이 자기 계발을 위해 시간을 보내고 있습니다. Q. 지원자에게 마지막으로 전하고 싶은 취업 팁은?A. 상대방의 의견을 들을 수 있는 자세가 되어 있어야 합니다. 어떤 집단에 들어간다는 것은 그 때부터 스스로를 조금은 놓아야 한다고 생각합니다. 회사생활은 혼자서는 해낼 수 없는 중요한 업무들로 가득 차 있습니다. 동료들과 함께 나아갈 수 있는 사람임을 어필할 수 있다면 좋은 점수를 받지 않을까요? 커뮤니케이션이 가장 중요한 포인트인 것 같네요.  “KT는 생활 밀착형 복지 혜택이 좋은 기업입니다.“- KT 소프트웨어개발단 GIS정보제공서비스개발TF 송민정Q. 현재 어떤 직무를 담당하고 계신가요?A. 현재 GIS(지리정보시스템)의 검색 파트에서 개발 업무를 담당하고 있어요. 구체적으로는 크게 3가지로 나눌 수 있는데 데이터 정제 및 현행화 모듈 개발, 검색 엔진 개발 및 질의 최적화, 테스팅 도구 개발을 진행하고 있습니다. GIS 분야, 특히 검색 서비스는 올해 제가 처음 하는 분야라 기술 리서치 하는데 상대적으로 시간을 많이 쓰고 있어요. 또한 기존 서비스와의 차별점을 내세우기 위해 고객 요구 사항뿐만 아니라 자체적으로 요구 사항을 만들어 적용해 보기도 합니다. 국내외 유수 기업 고객의 지도 서비스, 나아가 KT 내비와 지도의 검색서비스로 출시될 생각에 벌써 가슴이 설레네요. Q. KT를 선택한 이유는 무엇인가요?A. 대학교 때 친하게 지냈던 선배가 KT로 입사했어요. 그래서 자연스럽게 업무 환경이나 조직 분위기에 대해 알 수 있었는데, 그때 저에게 있어 KT 기업 이미지가 긍정적으로 생기기 시작했던 것 같아요. 대부제도나 경조사 지원정책, 자녀를 임신하거나 출산한 여성에게 친화적인 제도 등 생활 밀착형 복지가 잘 되어 있다고 들었는데, 실제로 입사 후에 혜택을 많이 받고 있어요. 또한 다양한 ICT 사업시도를 하고 있는 KT에서 SW개발자에 대한 중요성이 점점 강조되고 있고, 전폭적인 지원을 해주고 있다는 소식도 선택의 큰 이유였던 것 같아요.Q. 회사에서 가장 보람 있었던 일은 무엇인가요?A. 입사 1년 차에 담당했던 'KT 패밀리박스' 앱 서비스 개발 업무 때의 일이에요. 경험이 부족한데도 믿고 맡겨주신 선배님 덕분에 앱 리뉴얼 서버 개발에 상당 부분 참여하게 되었습니다. 지금 생각해보면 그때 같은 상황을 기회라고 하는 것 같아요. 크고 작은 실수가 있었지만 모두 한마음으로 이해해 주셨어요. 출시 임박해서는 여타 서비스 개발이 그러하듯이 다소 고된 시간이 있었지만, 사업부서와 협업이 잘되어 그 어느 때보다 즐겁게 일했어요. 무엇보다 자식 같은 서비스가 출시되었을 때의 기쁨은 이루 말할 수가 없었네요. Q. 하루 일과를 설명해주세요.A. 매일 오전 10시에 20-30분간 진행되는 팀 미팅이 있어요. 어제 한 일, 오늘 할 일, 이슈사항을 공유합니다. 월/수/금요일 점심시간에는 운동 동호회 활동을 해요. 회사 헬스장에서 트레이너 선생님을 모시고 회원들과 40여 분 운동을 하며 체력 관리도 하고 스트레스도 풀어요. 오후에는 특별한 일이 없으면 업무에 집중해서 개발 업무를 해요. 비교적 자유롭게 동료들과 대화하며 문제를 해결하거나 토론을 해요. 동료와 한 자리에 앉아 페어 코딩을 할 때도 있어요. 6시가 넘으면 팀장님께서는 퇴근을 장려하세요. 더하고 싶거나 잔업이 있는 경우에는 자율적으로 야근을 하지만, 가급적 일과 시간에 마치려고 노력하는 편입니다.“KT에는 격려와 조언을 아끼지 않는 선배님들이 있습니다.“- kt telecop 차세대IT추진단 IT구축팀 편광일Q. 현재 어떤 직무를 담당하고 계신가요?A. 저는 IT구축팀에서 ‘케이티텔레캅’ App을 담당하고 있습니다. ‘케이티텔레캅’ App은 kt telecop 서비스, 요금 조회, 상담 등 고객님들께 꼭 필요한 서비스를 하나의 App을 통해서 해결할 수 있는 기능을 가지고 있습니다. 저는 이런 ‘케이티텔레캅’ App과 관련하여 사업부서와 Daily Meeting을 하고, 추가 기능 개발 및 유지 보수를 진행합니다. 또한, 새로운 기능 개발에 있어서 협력업체와 co-work할 경우 협력업체 선택, 프로젝트에 대한 전반적인 일정 관리, 새로운 기능에 대한 전략을 제시합니다. Q. 회사에서 가장 보람 있었던 일은 무엇인가요?A. 제가 회사에서 가장 보람 있었던 일은 ‘케이티텔레캅’ App 기능 중 하나를 개발한 것입니다. 개발 당시 신입사원인 저에게 큰 부담이 되어 홀로 인터넷, 서적 등을 참고하며 수차례 야근도 했습니다. ‘과연 내가 해낼 수 있을까?’라는 생각을 할 때쯤 팀 선배님들께서 이를 알아차리고, 격려와 함께 부족한 부분에 대한 조언과 자료 공유를 통해 하나씩 차근히 진행할 수 있도록 도와주셨습니다. 그 결과 무사히 프로젝트를 완료할 수 있었고, 이는 저를 응원해 주고 격려해 주는 선배님들이 있었기에 가능했다고 생각합니다. 신입사원 분들도 업무를 진행 할 때, 힘든 점이 있다고 혼자 고민하기보다 선배님 혹은 동기들에게 도움을 요청하면 더 좋은 결과를 얻을 수 있을 것입니다.Q. 하루 일과를 설명해주세요.A. 출근 후, 팀 동료들과 반가운 인사를 나누며 하루를 시작합니다. 오늘 해야 할 일들을 우선순위로 작성하고, 월/수/금요일에는 KT그룹의 사내방송(KBN)을 시청합니다.9시 - 팀 회의를 통해 그날의 이슈사항과 각자 할 일에 대해 공유합니다.10시 - 회사 내 시스템을 모니터링하며 실시간 상황을 체크합니다. 협력사와 함께 프로젝트 개발 이슈를 정리하고, 보완해야 할 부분은 직접 개발합니다.12시 - 즐거운 점심시간입니다! 저희 회사 지하에 위치한 구내식당 밥의 맛과 영양은 정말 최고입니다^^ 식사를 마치면 팀장님과 팀원들 모두 사다리 타기, 다트 등을 통해 음료 사주기 시간을 갖습니다.13시 - 점심 먹고 졸린 시간인 만큼 팀 내부적으로 안마해주기, 재미있는 이야기 하기 등으로 식곤증을 극복합니다.14시 - 사업부서와 시스템에 대한 추가 요구사항이나 이슈에 대해 공유하는 회의를 진행합니다. 회의를 통해 새롭게 도출된 요구사항을 시스템에 반영하고 수정∙보완합니다.18시 - 하루의 일과를 마치고 퇴근시간을 갖습니다. 특히, 매주 수요일은 ‘가족사랑의 날’이기 때문에 본부장님, 팀장님들과 함께 정시 퇴근합니다. Q. 지원자에게 마지막으로 전하고 싶은 취업 팁은?A. 대부분 취업준비생들은 자기소개서를 작성할 때, 회사 홈페이지 혹은 기사를 참고하면서 쓰곤 하는데, 저는 다른 지원자들보다 차별화를 두기 위해서 직접 본사에 찾아가 선배님들에게 많은 이야기를 들으려고 노력했습니다. 또한, ‘우수기업-청년 채용박람회’에 참석해 kt telecop 부스에서 인사지원팀 과장님들과 이야기를 나누며 회사에 대한 정보를 얻고, 저에 대해 강한 어필을 했습니다. 이 때 보여드린 ‘저의 입사 의지와 진정성이 합격에 결정적인 역할을 하지 않았나!’라는 생각을 하게 됩니다. 신입 공채를 지원하는 후배님들도 남들과는 다른 차별성을 갖고 우리kt telecop에 지원하게 된다면, 분명 좋은 결과를 얻을 수 있을 것입니다.지난주 영업/마케팅 직무에 이어 지금까지 IT 직무를 맡고 계신 KT人들의 이야기를 들어봤는데요. KT의 핵심 기술을 담당하고 있는 KT人들의 인터뷰를 보니, KT가 바라는 인재상에 대해 감이 잡히는 것 같지 않나요? 특히, IT 직무에 필요한 주요 역량으로는 동료∙고객사와의 원활한 커뮤니케이션 능력과 더불어, 체계적인 분석력과 참신한 개발능력이 필요할 것 같습니다. 이와 함께, IT분야에 종사하는 KT人들의 취업 핵심 팁은 자소서를 진솔하고 꼼꼼하게 쓸 것, 면접 시 자연스럽고 일관된 태도를 보이는 것, 그리고 입사 후 동료들과 협력하여 직무를 수행해낼 수 있는 가능성을 보이는 것! 여러분도 모두 해낼 수 있을 겁니다. KT 직무 인터뷰는 다음주에 더욱 풍성한 이야기로 찾아오겠습니다. 안녕!#kt #기업문화 #사내문화 #조직문화 #복지혜택 #kt공채 #하루일과 #kt일상 #구성원인터뷰 #직무정보
조회수 1034

안드로이드 클라이언트 Reflection 극복기 - VCNC Engineering Blog

 비트윈 팀은 비트윈 안드로이드 클라이언트(이하 안드로이드 클라이언트)를 가볍고 반응성 좋은 애플리케이션으로 만들기 위해 노력하고 있습니다. 이 글에서는 간결하고 유지보수하기 쉬운 코드를 작성하기 위해 Reflection을 사용했었고 그로 인해 성능 이슈가 발생했던 것을 소개합니다. 또한 그 과정에서 발생한 Reflection 성능저하를 해결하기 위해 시도했던 여러 방법을 공유하도록 하겠습니다.다양한 형태의 데이터Java를 이용해 서비스를 개발하는 경우 POJO로 서비스에 필요한 다양한 모델 클래스들을 만들어 사용하곤 합니다. 안드로이드 클라이언트 역시 모델을 클래스 정의해 사용하고 있습니다. 하지만 서비스 내에서 데이터는 정의된 클래스 이외에도 다양한 형태로 존재합니다. 안드로이드 클라이언트에서 하나의 데이터는 아래와 같은 형태로 존재합니다.JSON: 비트윈 서비스에서 HTTP API는 JSON 형태로 요청과 응답을 주고 받고 있습니다.Thrift: TCP를 이용한 채팅 API는 Thrift를 이용하여 프로토콜을 정의해 서버와 통신을 합니다.ContentValues: 안드로이드에서는 Database 에 데이터를 저장할 때, 해당 정보는 ContentValues 형태로 변환돼야 합니다.Cursor: Database에 저장된 정보는 Cursor 형태로 접근가능 합니다.POJO: 변수와 Getter/Setter로 구성된 클래스 입니다. 비지니스 로직에서 사용됩니다.코드 전반에서 다양한 형태의 데이터가 주는 혼란을 줄이기 위해 항상 POJO로 변환한 뒤 코드를 작성하기로 했습니다.다양한 데이터를 어떻게 상호 변환할 것 인가?JSON 같은 경우는 Parsing 후 Object로 변환해 주는 라이브러리(Gson, Jackson JSON)가 존재하지만 다른 형태(Thrift, Cursor..)들은 만족스러운 라이브러리가 존재하지 않았습니다. 그렇다고 모든 형태에 대해 변환하는 코드를 직접 작성하면 필요한 경우 아래와 같은 코드를 매번 작성해줘야 합니다. 이와 같이 작성하는 경우 Cursor에서 원하는 데이터를 일일이 가져와야 합니다.@Override public void bindView(View view, Context context, Cursor cursor) { final ViewHolder holder = getViewHolder(view); final String author = cursor.getString("author"); final String content = cursor.getString("content"); final Long timeMills = cursor.getLong("time"); final ReadStatus readStatus = ReadStatus.fromValue(cursor.getString("readStatus")); final CAttachment attachment = JSONUtils.parseAttachment(cursor.getLong("createdTime")); holder.authorTextView.setText(author); holder.contentTextView.setText(content); holder.readStatusView.setReadStatus(readStatus); ... } 하지만 각 형태의 필드명(Key)이 서로 같도록 맞춰주면 각각의 Getter와 Setter를 호출해 형태를 변환해주는 Utility Class를 제작할 수 있습니다.@Override public void bindView(View view, Context context, Cursor cursor) { final ViewHolder holder = getViewHolder(view); Message message = ReflectionUtils.fromCursor(cursor, Message.class); holder.authorTextView.setText(message.getAuthor()); holder.contentTextView.setText(message.getContent()); holder.readStatusView.setReadStatus(message.getReadStatus()); ... } 이런 식으로 코드를 작성하면 이해하기 쉽고, 모델이 변경되는 경우에도 유지보수가 비교적 편하다는 장점이 있습니다. 따라서 필요한 데이터를 POJO로 작성하고 다양한 형태의 데이터를 POJO로 변환하기로 했습니다. 서버로부터 받은 JSON 혹은 Thrift객체는 자동으로 POJO로 변환되고 POJO는 다시 ContentValues 형태로 DB에 저장됩니다. DB에 있는 데이터를 화면에 보여줄때는 Cursor로부터 데이터를 가져와서 POJO로 변환 후 적절한 가공을 하여 View에 보여주게 됩니다.POJO 형태로 여러 데이터 변환필요Reflection 사용과 성능저하처음에는 Reflection을 이용해 여러 데이터를 POJO로 만들거나 POJO를 다른 형태로 변환하도록 구현했습니다. 대상 Class의 newInstance/getMethod/invoke 함수를 이용해 객체 인스턴스를 생성하고 Getter/Setter를 호출하여 값을 세팅하거나 가져오도록 했습니다. 앞서 설명한 ReflectionUtils.fromCursor(cursor, Message.class)를 예를 들면 아래와 같습니다.public T fromCursor(Cursor cursor, Class clazz) { T instance = (T) clazz.newInstance(); for (int i=0; i Reflection을 이용하면 동적으로 Class의 정보(필드, 메서드)를 조회하고 호출할 수 있기 때문에 코드를 손쉽게 작성할 수 있습니다. 하지만 Reflection은 튜토리얼 문서에서 설명된 것처럼 성능저하 문제가 있습니다. 한두 번의 Relfection 호출로 인한 성능저하는 무시할 수 있다고 해도, 필드가 많거나 필드로 Collection을 가진 클래스의 경우에는 수십 번이 넘는 Reflection이 호출될 수 있습니다. 실제로 이 때문에 안드로이드 클라이언트에서 종종 반응성이 떨어지는 경우가 발생했습니다. 특히 CursorAdapter에서 Cursor를 POJO로 변환하는 코드 때문에 ListView에서의 스크롤이 버벅이기도 했습니다. Bytecode 생성 Reflection 성능저하를 해결하려고 처음으로 선택한 방식은 Bytecode 생성입니다. Google Guice 등의 다양한 자바 프로젝트에서도 Bytecode를 생성하는 방식으로 성능 문제를 해결합니다. 다만 안드로이드의 Dalvik VM의 경우 일반적인 JVM의 Bytecode와는 스펙이 다릅니다. 이 때문에 기존의 자바 프로젝트에서 Bytecode 생성에 사용되는 CGLib 같은 라이브러리 대신 Dexmaker를 이용하여야 했습니다. CGLib CGLib는 Bytecode를 직접 생성하는 대신 FastClass, FastMethod 등 펀리한 클래스를 이용할 수 있습니다. FastClass나 FastMethod를 이용하면 내부적으로 알맞게 Bytecode를 만들거나 이미 생성된 Bytecode를 이용해 비교적 빠른 속도로 객체를 만들거나 함수를 호출 할 수 있습니다. public T create() { return (T) fastClazz.newInstance(); } public Object get(Object target) { result = fastMethod.invoke(target, (Object[]) null); } public void set(Object target, Object value) { Object[] params = { value }; fastMethod.invoke(target, params); }  Dexmaker 하지만 Dexmaker는 Bytecode 생성 자체에 초점이 맞춰진 라이브러리라서 FastClass나 FastMethod 같은 편리한 클래스가 존재하지 않습니다. 결국, 다음과 같이 Bytecode 생성하는 코드를 직접 한땀 한땀 작성해야 합니다. public DexMethod generateClasses(Class<?> clazz, String clazzName){ dexMaker.declare(declaringType, ..., Modifier.PUBLIC, TypeId.OBJECT, ...); TypeId<?> targetClassTypeId = TypeId.get(clazz); MethodId invokeId = declaringType.getMethod(TypeId.OBJECT, "invoke", TypeId.OBJECT, TypeId.OBJECT); Code code = dexMaker.declare(invokeId, Modifier.PUBLIC); if (isGetter == true) { Local<Object> insertedInstance = code.getParameter(0, TypeId.OBJECT); Local instance = code.newLocal(targetClassTypeId); Local returnValue = code.newLocal(TypeId.get(method.getReturnType())); Local value = code.newLocal(TypeId.OBJECT); code.cast(instance, insertedInstance); MethodId executeId = ... code.invokeVirtual(executeId, returnValue, instance); code.cast(value, returnValue); code.returnValue(value); } else { ... } // constructor Code constructor = dexMaker.declare(declaringType.getConstructor(), Modifier.PUBLIC); Local<?> thisRef = constructor.getThis(declaringType); constructor.invokeDirect(TypeId.OBJECT.getConstructor(), null, thisRef); constructor.returnVoid(); }  Dexmaker를 이용한 방식을 구현하여 동작까지 확인했으나, 다음과 같은 이유로 실제 적용은 하지 못했습니다. Bytecode를 메모리에 저장하는 경우, 프로세스가 종료된 이후 실행 시 Bytecode를 다시 생성해 애플리케이션의 처음 실행성능이 떨어진다.Bytecode를 스토리지에 저장하는 경우, 원본 클래스가 변경됐는지를 매번 검사하거나 업데이트마다 해당 스토리지를 지워야 한다.더 좋은 방법이 생각났다. Annotation Processor 최종적으로 저희가 선택한 방식은 컴파일 시점에 형태변환 코드를 자동으로 생성하는 것입니다. Reflection으로 접근하지 않아 속도도 빠르고, Java코드가 미리 작성돼 관리하기도 편하기 때문입니다. POJO 클래스에 알맞은 Annotation을 달아두고, APT를 이용해 Annotation이 달린 모델 클래스에 대해 형태변환 코드를 자동으로 생성했습니다. 형태 변환이 필요한 클래스에 Annotation(@GenerateAccessor)을 표시합니다. @GenerateAccessor public class Message { private Integer id; private String content; public Integer getId() { return id; } ... }  javac에서 APT 사용 옵션과 Processor를 지정합니다. 그러면 Annotation이 표시된 클래스에 대해 Processor의 작업이 수행됩니다. Processor에서 코드를 생성할 때에는 StringBuilder 등으로 실제 코드를 일일이 작성하는 것이 아니라 Velocity라는 template 라이브러리를 이용합니다. Processor는 아래와 같은 소스코드를 생성합니다. public class Message$$Accessor implements Accessor { public kr.co.vcnc.binding.performance.Message create() { return new kr.co.vcnc.binding.performance.Message(); } public Object get(Object target, String fieldName) throws IllegalArgumentException { kr.co.vcnc.binding.performance.Message source = (kr.co.vcnc.binding.performance.Message) target; switch(fieldName.hashCode()) { case 3355: { return source.getId(); } case -1724546052: { return source.getContent(); } ... default: throw new IllegalArgumentException(...); } } public void set(Object target, String fieldName, Object value) throws IllegalArgumentException { kr.co.vcnc.binding.performance.Message source = (kr.co.vcnc.binding.performance.Message) target; switch(fieldName.hashCode()) { case 3355: { source.setId( (java.lang.Integer) value); return; } case -1724546052: { source.setContent( (java.lang.String) value); return; } ... default: throw new IllegalArgumentException(...); } } }  여기서 저희가 정의한 Accessor는 객체를 만들거나 특정 필드의 값을 가져오거나 세팅하는 인터페이스로, 객체의 형태를 변환할 때 이용됩니다. get,set 메서드는 필드 이름의 hashCode 값을 이용해 해당하는 getter,setter를 호출합니다. hashCode를 이용해 switch-case문을 사용한 이유는 Map을 이용하는 것보다 성능상 이득이 있기 때문입니다. 단순 메모리 접근이 Java에서 제공하는 HashMap과 같은 자료구조 사용보다 훨씬 빠릅니다. APT를 이용해 변환코드를 자동으로 생성하면 여러 장점이 있습니다. Reflection을 사용하지 않고 Method를 직접 수행해서 빠르다.Bytecode 생성과 달리 애플리케이션 처음 실행될 때 코드 생성이 필요 없고 만들어진 코드가 APK에 포함된다.Compile 시점에 코드가 생성돼서 Model 변화가 바로 반영된다. APT를 이용한 Code생성으로 Reflection 속도저하를 해결할 수 있습니다. 이 방식은 애플리케이션 반응성이 중요하고 상대적으로 Reflection 속도저하가 큰 안드로이드 라이브러리에서 최근 많이 사용하고 있습니다. (AndroidAnnotations, ButterKnife, Dagger) 성능 비교 다음은 Reflection, Dexmaker, Code Generating(APT)를 이용해 JSONObject를 Object로 변환하는 작업을 50번 수행한 결과입니다.성능 비교 결과 이처럼 최신 OS 버전일수록 Reflection의 성능저하가 다른 방법에 비해 상대적으로 더 큽니다. 반대로 Dexmaker의 생성 속도는 빨라져 APT 방식과의 성능격차는 점점 작아집니다. 하지만 역시 APT를 통한 Code 생성이 모든 환경에서 가장 좋은 성능을 보입니다. 마치며 서비스 모델을 반복적으로 정의하지 않으면서 변환하는 방법을 알아봤습니다. 그 과정에서 Reflection 의 속도저하, Dexmaker 의 단점도 설명해 드렸고 결국 APT가 좋은 해결책이라고 판단했습니다. 저희는 이 글에서 설명해 드린 방식을 추상화해 Binding이라는 라이브러리를 만들어 사용하고 있습니다. Binding은 POJO를 다양한 JSON, Cursor, ContentValues등 다양한 형태로 변환해주는 라이브러리입니다. 뛰어난 확장성으로 다양한 형태의 데이터로 변경하는 플러그인을 만들어서 사용할 수 있습니다. Message message = Bindings.for(Message.class).bind().from(AndroidSources.cursor(cursor)); Message message = Bindings.for(Message.class).bind().from(JSONSources.jsonString(jsonString)); String jsonString = Bindings.for(Message.class).bind(message).to(JSONTargets.jsonString());  위와 같이 Java상에 존재할 수 있는 다양한 타입의 객체에 대해 일종의 데이터 Binding 기능을 수행합니다. Binding 라이브러리도 기회가 되면 소개해드리겠습니다. 윗글에서 궁금하신 점이 있으시거나 잘못된 부분이 있으면 답글을 달아주시기 바랍니다. 감사합니다. 
조회수 1727

[인터뷰]미미박스의 TECHNOLOGY를 이끄는 CTO KAY를 만나다

안녕하세요. Ava입니다.여러분에게 더 건강하고, 아름다운 라이프스타일을 제공하기 위해 노력하는 미미박스 뒤에는여러분의 니즈를 만족시키고 안정된 서비스를 제공하기 위한 개발이끊임없이 진행되고 있습니다.오늘은 미미박스 TECHNOLOGY UNIT를이끌고 계신 김종광 CTO(이하 KAY) 님을 소개해드리겠습니다.KAY는 대기업과 IT기업에서 앱 개발과 웹 개발을 진행했던 커리어를 갖고 계신데요. 경력과 전문성 뿐만 아니라 개발자들이 상상할 수 있는 문화를 강조하며 만들어나가고 있습니다.항상 푸근한 아빠 미소로 미미박서의 질문과 제안을 받아주고,열린 리더의 모습을 보여주시는 KAY를 소개합니다.김종광 (Kay) 한국기술교육대학교 전기전자공학 석사전) NC소프트전) SK communicationsUNIT1. KAY를 소개해주세요.Q. 안녕하세요. 항상 아빠 미소를 짓고 계신 KAY~KAY를 소개해주세요.A. 처음에 미미박스에 모바일 앱 개발 총괄로 입사했어요. 지금은 개발 UNIT 전체를 맡고 있고요. 세 가지의 주 업무가 있는데요. 개발 전체 프로젝트를 leading 하고 다른 팀과 연관된 업무에 대해서 지원하는 일과, 새로운 개발자를 충원하는 업무를 하고 있습니다.Q. 미미박스에 입사하시게 된 계기는 무엇인가요? A. 처음에는 지인이 추천해서 미미박스를 알게 되었어요. 그 후에 미미박스에 대해 조사를 해봤죠. 비즈니스 모델, 성장 가능성을 봤을 때 '될 것 같다'는 생각을 가졌어요. 그리고 몇 번 찾아갔었는데 회사 분위기가 활기차고 재밌었어요. 그리고 일하는 사람들 중에 아는 사람들이 4~5명 정도 더 있었어요. 이분들과 다른 구성원들을 보면서 '이 친구들이랑 같이 일하면 즐겁게 일할 수 있겠다'라는 생각이 들었죠.Q. 여러 조직에서 있으셨던 만큼 개발 업무 자체에 대한 이유도 있을 것 같아요. A. 보통 기업에서는 개발자의 역할이 상당히 제한되어있어요. 업무에 대한 의사결정 권한이 거의 없죠. TOP-DOWN 방식으로 내려온 것들을 그냥 해야 하는 경우가 많거든요. 개발자들은 다들 알 거예요. 만들면서 '이거 안될 것 같다.'라는 감이 있는데, 느낌상으로 안될 것 같은 것을 만드니까 의욕이 생기지 않는 경우가 있었어요. 효과성보다는 어떤 서비스를 오픈했다는 것 자체가 실적이 되는 경우가 많거든요. Q. 그런 경우가 있군요. 그렇다면 미미박스 내에서는 개발 업무에 대해 어떤 식으로 의사결정이 이루어지나요?A. 업무에 대한 의사결정은 반반인 것 같아요. 우선 TECHNOLOGY UNIT 내부에서 프로젝트를 진행하는 것이 있어요. '이렇게 하면 회사와 서비스에 도움이 되겠다. 매출도 좋아질 것 같다. 사람들도 좋아할 것 같다'이런 의견을 내고 직접 만들 수 있고요. 서비스를 같이 진행하는 마케팅팀이나 플랫폼 운영팀에서 요청이 들어오면 그 요청에 대해 저희가 납득하고 하면 좋겠다고 생각하는 업무에 대해서 일정을 짜고 진행해요. 각 요소 별로 개발 측면의 논의도 많이 하고 실제 만드는 사람의 의견이 많이 반영됩니다. Q. 직접 만들고 구축하는 사람들의 의견은 정말 중요한 것 같아요.TECHNOLOGY UNIT을 이끌고 있는 UNIT 장님으로서 KAY의 하루 스케줄은 어떻게 되나요?A. 출근 후, 오전에는 집중 개발 업무를 하고 있어요. 제가 플랫폼 개발 팀장도 겸임하고 있거든요. 오후부터는 대부분 팀미팅이나 프로젝트 미팅을 많이 합니다. 프로젝트의 진행사항을 체크하고, 개발이 어려운 부분과 개발하면서 중요하게 생각하는 부분에 대해서 토론하죠. 그리고 새로운 개발 인력들 채용을 위해 면접을 많이 봅니다.Q. TECHNOLOGY UNIT 내부에서 소통과 역량 강화를 위해 주기적으로 여는 세션이 있다고 들었는데 소개해주세요!A. 일주일에 한 번씩 주니어 개발자를 대상으로 스터디를 진행하고 있습니다. 저는 스터디를 leading 하고 멘토 역할을 하고 있고요.이런 시간을 만들게 된 이유는 소통의 장을 만들고 개발자들의 역량을 키우기 위해서입니다.주니어 개발자들이 시니어 개발자들 앞에서 의견을 내는 것에 대해서 소극적인 면이 있어요. 틀릴까 봐 의견을 쉽게 못 내죠. 그래서 주니어 개발자들끼리 모여서 얘기할 공간을 만들어 주는 것이 중요하다고 생각했어요. 서로 의견을 내고 토론하면서 개발에 대한 역량도 쌓고 의견을 내는 훈련도 할 수 있죠.그리고 DATA UNIT의 협조를 받아서 빅데이터 관련 스터디를 진행하고 있어요. 그래서 개발자들 중 관심 있는 사람이들 모여서 빅데이터 관련 LOGIC을 만들어보고, 아이디어를 실현시켜보는 작은 프로젝트를 그룹별로 진행하고 있어요.앞으로는 이런 세션들을 발전시켜 세미나를 열 예정이에요. 그래서 각 개발자들이 적어도 1년에 2번 이상은 주제 발표할 수 있도록 환경을 만들려고 합니다. 개발 업무는 집중도가 높아서 건조해질 위험이 있어요. 집중하다 보면 일에 치여서 자기계발이 어려워질 수 있기 때문에 계속 자기계발하는 분위기를 만들어가려고 합니다. 전사적으로도 그런 분위기가 계속 만들어지면 좋겠어요.Q. 건조하긴요! 제가 보기엔 개발팀들이 가장 활발하고 참여도도 높은 것 같은데요! 열려있는 분들도 많고요.A. 개발팀이 아닌 팀들이랑 많이 소통하라고 조언을 많이 해요. 미미투게더(2개 이상 팀이 함께 회식하면 회식비를 지원해주는 기업문화 제도)를 할 때도 개발팀 내부에서만 하지 말고 무조건 다른 팀들과 함께하라고 하고 있어요. 새로운 아이디어를 나눌 수 있고 인간관계가 힘이 될 때가 많기 때문에 다른 팀들이랑 얘기를 많이 나누는 게 필요하죠. UNIT2. TECHNOLOGY UNIT을 소개해주세요.Q. TECHNOLOGY UNIT을 소개해주세요.A. TECHNOLOGY UNIT에서는 지금 미미박스에서 서비스하는 모든 PRODUCT, 플랫폼, 모바일 앱, PC 웹, 내부 직원들이 쓰는 모든 것들을 개발하고 있습니다. 대부분의 기업에서는 계약직이나 파견직의 고용형태로 진행하는 경우도 있는데, 저희는 모든 구성원이 정직원으로 개발 업무를 하고 있습니다.Q. TECHNOLOGY UNIT의 분위기는 어떤가요?A. 개발자라는 직무를 하는 사람들은 생각 자체가 자유로워야 합니다. 경직되어있으면 좋은 아이디어가 떠오르지 않죠. 그래서 TECHNOLOGY UNIT은 최소한의 규제나 룰을 두고 자유롭게 활동하게 하고 있어요. 특별한 일이 아니면 회의 소집도 지양하고 있어요.다양하게 상상하려면 경직되지 않고, 룰에 집착하지 않는 문화를 만들어야 하기 때문이에요. 그래야 본인의 의견도 편하게 이야기할 수 있죠. 구성원들을 보면 시니어 개발자들은 적응을 잘해요. 주니어 개발자들이 아직 조금 경직되어있긴 해요.지금 신입 공채 2기를 뽑고 있는데요. 보통은 스타트업에서 입사 후 바로 투입될 수 있는 사람을 뽑아요. 하지만 저는 확신이 있어서 저희 미미박스의 DNA를 가지고 처음부터 함께할 수 있는 신입을 뽑고 싶어요. 미미박스의 DNA를 가지고 더 성장하게 되면 저희 개발 조직에 기둥이 될 수 있을 거라고 생각합니다. <채용공고 보러 가기 클릭>Q. KAY와 함께 하는 구성원들이 점점 부러워지네요. 정말 구성원들의 성장에 많은 비중을 두고 여러 계획을 실천하는 것 같아요. 미미박스에는 여성 개발자도 점점 많아지는 것 같은데 재미있는 에피소드 있나요?A. 먼저 여성 개발자들의 비중이 점점 늘어나고 있어요. 우리가 여성 고객을 위한 서비스를 많이 하고 있잖아요. 그 감성을 같이 공유할 수 있는 사람이 많아지면 기술적인 부분뿐 아니라 감성적인 부분에서도 큰 시너지가 나죠. 실제로 웹페이지에 제품 가격이 잘못 올라간 적이 있어요. 저희 남성 개발자들이 그 데이터를 먼저 보는데 '이게 맞는 가격인가' 의심하는 사람이 아무도 없었어요. 그때 여성 개발자분이 '이 제품이 이 가격이 아닐 텐데? 문제를 제기했고 다행히 수정할 수 있었죠. Q. 그래도 남성 개발자들의 화장품 가격에 대한 감이 점점 정확해질 것 같아요. 호호KAY 님이 UNIT을 운영하시면서 가장 보람을 느끼신 적은 언제인가요?A. 고객들이 많이 와서 저희 서비스를 이용해 주실 때 보람을 느낍니다. 저희 UNIT 자체에서도 무언가를 만들어가고 있다는 것을 느끼고, 실제로 좋은 반응을 얻었을 때 기분이 정말 좋아요. Q. 점점 더 많은 분들이 미미박스를 찾아주신다는 게 느껴져요! 앞으로의 목표는 무엇인가요?A. 첫 번째는 글로벌로 플랫폼을 옮기는 것입니다. 저희 내부에서 개발한 플랫폼과 서비스가 점점 확대돼서 미미박스가 해외에 진출할 때마다 플랫폼을 그대로 이동시켜 글로벌화하는 것이 첫 번째 목표고요. 두 번째는 앞으로 온라인을 넘어 오프라인에 대한 서비스도 진행할 예정이에요. 현재 미미박스 플랫폼과 오프라인 요소의 연계성을 찾고 최고의 고객 경험을 만드는 것이죠. 일반적인 O2O 서비스를 넘어 대부분의 고객이 여성이기 때문에 IT 기술 자체가 숨어있고, 알아서 돌아가게 만드는 서비스를 만들 것입니다.미미박스는 뷰티에 대해서 많은 강점과 다양성을 가지고 있기 때문에 이런 것들을 통해 저희만 할 수 있는 서비스를 만들고 싶어요. 마지막은 Data-driven 방식을 더욱 견고히 가져가는 것이에요. 축적되어있는 경험과 데이터를 통해서 고객 맞춤형 서비스에 대한 역량을 강화하는 것이죠. Q. 글로벌 플랫폼, O2O 서비스, Data-driven 앞으로의 TECHNOLOGY UNIT이 만들어낼 것들이 기대돼요. 두근두근. 마지막으로 KAY가 TECHNOLOGY UNIT을 리드하면서 가장 집중하는 3가지가 무엇인지 궁금합니다. A. 가장 중요한 것은 우리 개발자들의 커리어를 관리해주는 것이에요. 이분들이 미미박스에 와서 자기의 역량이 발전하지 않고 정체되다면 제가 역할을 제대로 못했다는 뜻이거든요.그래서 구성원들이 고생을 하든 뭘 하든 해가 갈수록 성장할 수 있도록 관리하는 것에 집중하고 있어요. 두 번째는 우리가 TECH 조직이기 때문에 서비스가 아주 정상적으로 운영되는 것이 목표에요. 단순한 장애를 없애는 것뿐만 아니라 계속 플랫폼이 발전하면서 문제가 없게 만들어야 하죠. 매출, 데이터가 계속 쌓이면서 안정적인 서비스를 만드는 것, 기본적인 것 같지만 가장 중요한 것 같아요. 마지막으로는 Align이에요. 개발팀이 성장할 수 있는 서비스, 개발 역량을 강화시키다며 보면 회사의 목표에 Align 되는 것을 놓칠 수 있어요. 그렇기 때문에 개발자들이 관심 있는 것들과 회사의 목표를 Align시켜서 시너지 효과를 낼 수 있도록 집중하고 있습니다.UNIT2. TECHNOLOGY UNIT으로서 어떤 사람과 일하고 싶나요?Q. TECHNOLOGY UNIT에서 일하기 위하여 갖추어야 할 역량은 어떤 것이 있나요?A. 첫 번째로 성장 가능성을 봅니다. 성장 가능성에는 여러 가지 의미가 있지만 적극적이고, 새로운 지식에 대한 욕구가 항상 강한 사람이어야 합니다. 배우고 싶은 열망, 해보고 싶다는 열망을 가지고 실제 구체적으로 실행해본 경험이 있고, 뭔가를 해본 사람이 성장 가능성이 있는 사람이라고 생각합니다. 제가 면접을 볼 때마다 항상 물어보는 것이 '5년 후 계획, 5년 후 모습은 어떨 것 같아요?'에요. 면접자가 적극적으로 대답하면 '그것을 위해 어떤 실행계획이 있는지' 물어보죠.두 번째로는 스타트업 마인드 FIT이 맞는 것이에요. 저도 미미박스에 처음 왔을 때 힘들었어요. 갖춰져 있는 게 없었거든요. 하나부터 열까지 하려면 뭔가 어디서 걸리는 거예요. 큰 회사는 세팅이 다 되어있는데 말이죠. 그래서 뭔가를 하려면 그 업무뿐 아니라 처음부터 다 찾고 만들어야 해요. 이렇게 만들어가는 걸 좋아하는 사람이 있어요. 준비가 안되어있다고 불평하는 것이 아니라 부족한 환경에서 할 거리가 많은 것을 반기는 사람들. 이런 사람들은 '이것저것 해봐야지~' 신나있어요. 이런 마인드 FIT을 많이 봅니다.Q. 스타트업 마인드 FIT 정말 공간되는 말인 것 같아요. 저도 갖춰져있는 틀에서 무언가를 하는 것보다 이것저것 찾아서 만드는 걸 좋아하거든요! 그런 분들이 많이 오시면 재밌는 일이 많이 벌어질 것 같아요. 우리 미미박스의 비전은 'Beautify the people'인데요. 혹시 취업이나 이직을 준비하는 분들께 이것만은 아름답게 관리하라고 조언하고 싶은 게 있나요?A. 이력서와 경력기술서를 아름답게 해야 해요. 개발자들 중에 '내 역량만 좋으면 되지'라고 생각하시는 분들이 있는데 자신의 커리어 패스를 만드는 것도 중요하거든요. 회사에서 처음에 서류전형을 진행하는 게 많은 내용을 내포하고 있어요. 경력기술서의 내용이 부실하면 회사도 본인도 FIT이 맞는 곳을 찾기가 어려워지죠. 어디서든 인정받는 사람이 되려면 자신의 업무와 역할을 충실하게 표현한 경력기술서를 작성하라고 말씀드리고 싶네요.Q. 정말 실질적인 조언이네요. 누구보다 깊게 고민하고 집중한 일일수록 경력기술서와 이력서를 잘 쓸 수 있고 자신의 경력도 잘 전달할 수 있을 것 같아요.마지막으로 함께 일하고 있는 미미박서분들께도 한마디 해주세요!A. 제가 여기 처음 와서 한 이야기가 있어요. "여기가 제 마지막 회사입니다."그렇게 이야기한 이유는 미미박스의 성장 가능성, 발전 가능성을 보았고 믿음이 있기 때문이죠. 모두가 같이 노력한다면 원하는 것을 이룰 수 있을 거라 생각해요. 다 같이 파이팅!
조회수 1286

AWS CodeCommit. 배포 자동화 환경 만들기(브랜치별 Pipeline 구성)

편집자 주: 함께 보면 좋아요!애플리케이션 개발부터 배포까지, AWS CodeStarCodeStar + Lambda + SAM으로 테스트 환경 구축하기AWS Lambda + API Gateway로 API 만들어보자목차1. CodeStar 프로젝트 생성2. 템플릿 선택3. 프로젝트 정보 입력4. 프로젝트 생성 및 자동 배포 확인5. CodeCommit 접속6. staging 브랜치 생성7. index.py 수정 및 Commit8. 람다 실행 권한 변경9. 스택 생성 및 템플릿 소스 복사10. 템플릿 소스 붙여넣기 및 S3 버킷 URL 생성11. staging 브랜치용 CloudFormation 스택 생성(1)12. staging 브랜치용 CloudFormation 스택 생성(2)13. 파이프라인 설정14. AWS CodeCommit 연결15. CodeBuild16. CodeDeploy17. staging 브랜치용 파이프라인 생성 및 자동 릴리즈18. 작업 그룹 추가19. 파이프라인 실행 및 배포20. API Gateway 접속 및 엔드포인트 확인21. index.py 배포 확인OverviewAWS는 유용한 서비스를 많이 제공하지만, 이것들을 조합하고 사용하는 건 꽤나 번거롭습니다. CodeStar는 이런 고충을 해결해주고자 등장한 서비스입니다. 버전 관리(CodeCommit)부터 빌드(CodeBuild)와 배포(CodeDeploy), 모니터링(CloudWatch)까지 한 번에 프로젝트를 구성해줍니다. 여기서 한 발 더 나아가 브랜치(master, staging)마다 자동으로 빌드, 배포되도록 구성했습니다. 이 포스팅에서는 AWS CodeCommit과 AWS Lambda(Python)을 사용했습니다. 물론 다른 스택을 사용해도 괜찮습니다.Practice1.CodeStar 프로젝트를 생성하겠습니다. CodeStar로 접속해 프로젝트를 생성합니다. CodeStar를 처음 사용한다면 서비스 역할을 생성하라는 창부터 나옵니다. 역할을 생성하고 진행합니다.2.왼쪽 필터에서 웹 서비스, Python, AWS Lambda를 클릭하고 프로젝트 템플릿을 선택합니다.3.프로젝트 정보를 입력하고 AWS CodeCommit을 선택, 프로젝트를 생성합니다. 코드편집 도구설정은 건너뜁니다. 나중에 다시 설정할 수 있습니다.4.조금 기다리면 프로젝트가 생성됩니다. 오른쪽 아래의 엔드포인트로 접속하면 자동으로 생성되는 예제 프로젝트가 잘 배포된 것을 볼 수 있습니다. 클릭 몇 번으로 자동 빌드, 배포에 모니터링까지 가능한 프로젝트가 구성되었으니 이제 staging 브랜치를 생성하여 똑같이 구성하겠습니다.5.먼저 브랜치를 생성하겠습니다. CodeCommit에 접속해 왼쪽의 브랜치 메뉴를 클릭하면 아래와 같이 master 브랜치가 생성된 것을 볼 수 있습니다.6.브랜치 생성을 클릭해 브랜치 이름은 staging, 다음으로부터의 브랜치는 master를 선택합니다.7.생성된 staging 브랜치를 클릭하면 파일 리스트가 보입니다. master 브랜치와 결과 페이지를 구별하기 위해 index.py 파일을 임의로 수정하겠습니다. index.py > 편집을 클릭해 output 문자열을 수정하고 Commit합니다.8.CodeStar는 CloudFormation 서비스로 인프라 리소스를 관리합니다. CloudFormation은 ‘스택’이라는 개념을 사용해 설정을 구성하고 있습니다. 지금은 master 브랜치의 template.yml 파일을 사용해 master 브랜치용 스택이 생성되어 있는 상태입니다.문제는 여기에 기본적으로 람다(lambda) 실행 역할이 구성되어 있는데, 이 역할의 리소스 접근 권한은 master 브랜치 람다로 한정되어 있다는 것입니다.1)이 글에서는 staging용 람다 실행 권한을 별도로 생성하는 방법으로 문제를 해결했습니다. staging 브랜치의 template.yml 파일을 열어 Resources: LambdaExecutionRole: Properties: RoleName을 임의의 값으로 수정합니다. 저는 뒤에 ‘-staging’을 붙였습니다.9.CloudFormation 스택도 따로 생성합니다. AWS CloudFormation에 접속하면 기본적으로 생성된 스택을 볼 수 있습니다. 기존의 스택 템플릿에서 조금만 수정해 스택을 생성하면 되니 템플릿을 복사해오겠습니다.awscodestar-testproject-lambda를 클릭해 오른쪽의 ‘Designer에서 템플릿 보기/편집’을 클릭하면 템플릿 소스를 볼 수 있습니다. 가장 아래의 템플릿 탭이 클릭되어 있는지 확인하고 그대로 복사합니다.10.다시 CloudFormation으로 돌아와 템플릿 디자인 버튼을 클릭하고 복사한 소스를 붙여 넣습니다. 여기서 마찬가지로 Resources: LambdaExecutionRole: Properties: RoleName을 조금 전의 이름과 같게 수정하고 저장합니다. 템플릿 언어를 YAML로 바꾸고 수정하면 보기 편합니다.Amazon S3 버킷에 저장하면 템플릿 파일이 S3 버킷에 저장되며 S3 버킷 URL이 생성됩니다. 잘 복사해둡니다. 템플릿 디자이너는 이제 닫아도 됩니다11.CloudFormation 창에서 스택 생성을 클릭해 Amazon S3 템플릿 URL에 복사한 URL을 입력합니다. 이후의 내용은 스택 이름만 다르게 하고, 나머지는 기본적으로 생성된 스택 정보와 동일하게 입력합니다. 기존에 생성한 스택 정보는 스택 상세 페이지 오른쪽의 스택 업데이트를 클릭하면 볼 수 있습니다.생성 페이지 마지막의 ‘AWS CloudFormation에서 사용자 지정 이름을 갖는 IAM 리소스를 생성할 수 있음을 승인합니다’를 체크하고 생성을 클릭합니다.12.staging 브랜치용 CloudFormation 스택이 생성되었습니다. 이 스택을 사용해 staging 브랜치용 파이프라인을 생성하겠습니다.13.CodePipeline으로 접속해 파이프라인 생성을 클릭하면 설정창으로 이동하는데, 아래 이미지와 같이 입력합니다.CodeStar프로젝트가 생성되며 IAM 역할과 S3 버킷이 자동 생성되는데, 동일한 역할과 버킷으로 설정하면 됩니다. 파이프라인 이름만 임의로 다르게 넣어줍니다.14.AWS CodeCommit을 연결해야 합니다. 아래와 같이 자동 생성된 리포지토리를 선택하고 미리 생성한 staging 브랜치를 연결합니다.15.CodeBuild를 알아보겠습니다. 기본 파이프라인에서 자동 생성된 프로젝트를 선택하고 다음을 클릭합니다.16.새 창을 열어 기존에 생성된 파이프라인 상세 페이지로 접속합니다. 편집을 클릭하고 Deploy 스테이지 편집을 클릭, GenerateChangeSet 편집 버튼을 클릭하면 설정값이 보입니다. 이 값을 참고해 다음 스텝을 아래와 같이 진행하면 됩니다.앞서 생성했던 staging 브랜치 파이프라인용 스택을 연결하고, 세트 이름을 임의로 다르게 넣습니다. ‘템플릿’과 ‘템플릿 구성 - 선택 사항’ 설정값도 다르니 주의합니다.17.다음으로 진행하면 staging 브랜치용 파이프라인이 생성되어 자동으로 릴리즈되고 있는 것을 볼 수 있습니다.18.여기서 master 파이프라인과 동일하게 Deploy 스테이지의 GenerateChangeSet 아래에 작업 그룹을 하나 추가해야 합니다. 마찬가지로 master 파이프라인을 참고해 작성힙니다. 작업이름, 새로 생성한 스택, staging용으로 임의 작성했던 세트 이름을 넣습니다.19.저장 후, 변경사항 릴리스를 클릭하면 파이프라인이 실행됩니다. 잠시 기다리면 완료와 함께 배포작업까지 이뤄집니다.20.모든 작업이 끝났습니다! 제대로 구성되었는지 엔드포인트로 접속해 확인해보겠습니다. AWS API Gateway로 접속해 staging 브랜치용 API Gateway를 클릭합니다.21.왼쪽의 스테이지 메뉴를 클릭하면 엔드포인트 URL을 볼 수 있습니다. 이 URL로 접속하면 위에서 편집한 staging 브랜치의 index.py가 배포된 것을 볼 수 있습니다. master 브랜치의 엔드포인트로도 접속해서 비교해보세요.ConclusionAWS의 서비스들은 강력하고 다양합니다. 그 수가 많아져 이제는 전부 다루기는커녕 나열하기도 어려울 정도입니다. 아마존에서도 이런 고충을 알기 때문에 여러 서비스를 묶어 간편하게 세팅하는 CodeStar를 제공하는 게 아닌가 싶습니다. 수가 많은 만큼 각각의 서비스를 정확히 이해하고 적절히 이용해 오버엔지니어링을 피하는 게 중요하겠습니다.참고1) IAM - 역할 - Permission boundary에서 확인 가능합니다글양정훈 사원 | R&D 개발3팀[email protected]브랜디, 오직 예쁜 옷만
조회수 3141

Apache Spark에서 컬럼 기반 저장 포맷 Parquet(파케이) 제대로 활용하기 - VCNC Engineering Blog

VCNC에서는 데이터 분석을 위해 다양한 로그를 수집, 처리하는데 대부분은 JSON 형식의 로그 파일을 그대로 압축하여 저장해두고 Apache Spark으로 처리하고 있었습니다. 이렇게 Raw data를 바로 처리하는 방식은 ETL을 통해 데이터를 전처리하여 두는 방식과 비교하면 데이터 관리비용에서 큰 장점이 있지만, 매번 불필요하게 많은 양의 데이터를 읽어들여 처리해야 하는 아쉬움도 있었습니다.이러한 아쉬움을 해결하기 위해 여러 논의 중 데이터 저장 포맷을 Parquet로 바꿔보면 여러가지 장점이 있겠다는 의견이 나왔고, 마침 Spark에서 Parquet를 잘 지원하기 때문에 저장 포맷 변경 작업을 하게 되었습니다. 결론부터 말하자면 74%의 저장 용량 이득, 10~30배의 처리 성능 이득을 얻었고 성공적인 작업이라고 평가하지만 그 과정은 간단하지만은 않았습니다. 그 과정과 이를 통해 깨달은 점을 이 글을 통해 공유해 봅니다.Parquet(파케이)에 대해Parquet(파케이)는 나무조각을 붙여넣은 마룻바닥이라는 뜻을 가지고 있습니다. 데이터를 나무조각처럼 차곡차곡 정리해서 저장한다는 의도로 지은 이름이 아닐까 생각합니다.Parquet을 구글에서 검색하면 이와 같은 마룻바닥 사진들이 많이 나옵니다.빅데이터 처리는 보통 많은 시간과 비용이 들어가므로 압축률을 높이거나, 데이터를 효율적으로 정리해서 처리하는 데이터의 크기를 1/2 혹은 1/3로 줄일 수 있다면 이는 매우 큰 이득입니다. 데이터를 이렇게 극적으로 줄일 수 있는 아이디어 중 하나가 컬럼 기반 포맷입니다. 컬럼 기반 포맷은 같은 종류의 데이터가 모여있으므로 압축률이 더 높고, 일부 컬럼만 읽어 들일 수 있어 처리량을 줄일 수 있습니다.https://www.slideshare.net/larsgeorge/parquet-data-io-philadelphia-2013Parquet(파케이)는 하둡 생태계의 어느 프로젝트에서나 사용할 수 있는 효율적인 컬럼 기반 스토리지를 표방하고 있습니다. Twitter의 “Julien Le Dem” 와 Impala 프로젝트 Lead였던 Cloudera의 “Nong Li”가 힘을 합쳐 개발한 프로젝트로 현재는 많은 프로젝트에서 Parquet를 지원하고 컬럼 기반 포맷의 업계 표준에 가깝습니다.Parquet를 적용해보니 Apache Spark에서는, 그리고 수많은 하둡 생태계의 프로젝트들에서는 Parquet를 잘 지원합니다.val data = spark.read.parquet("PATH") data.write.parquet("PATH") Spark에서는 이런 식으로 손쉽게 parquet 파일을 읽고, 쓸 수가 있습니다. 데이터를 분석하기 전에 원본이라고 할 수 있는 gzipped text json을 읽어서 Parquet 로 저장해두고 (gzipped json은 S3에서 glacier로 이동시켜버리고), 이후에는 Parquet에서 데이터를 읽어서 처리하는 것 만으로도 저장용량과 I/O 면에서 어느 정도의 이득을 얻을 수 있었습니다. 하지만 테스트 결과 저장용량에서의 이득이 gz 23 GB 에서 Parquet 18GB 로 1/3 정도의 저장용량을 기대했던 만큼의 개선이 이루어지지는 않았습니다.Parquet Deep Dive상황을 파악하기 위해 조금 더 조사를 해보기로 하였습니다. Parquet의 포맷 스팩은 Parquet 프로젝트에서 관리되고 있고, 이의 구체적인 구현체로 parquet-mr 이나 parquet-cpp 프로젝트 등에서 스펙을 구현하고 있습니다. 그리고 특별한 경우에는 Spark에서는 Spark 내부에 구현된 VectorizedParquetRecordReader 에서 Parquet 파일을 처리하기도 합니다.파일 포맷이 바뀌거나 기능이 추가되는 경우에는 쿼리엔진에서도 이를 잘 적용해주어야 합니다. 하지만 안타깝게도 Spark은 parquet-mr 1.10 버전이 나온 시점에도 1.8 버전의 오래된 버전의 parquet-mr 코드를 사용하고 있습니다. (아마 다음 릴리즈(2.4.0)에는 1.10 버전이 적용될 것으로 보이지만)Parquet 의 메인 개발자 중에는 Impala 프로젝트의 lead도 있기 때문에, Impala에는 비교적 빠르게 변경사항이 반영되는 것에 비하면 대조적입니다. 모든 프로젝트들이 실시간적으로 유기적으로 업데이트되는 것은 힘든 일이기 때문에 어느 정도는 받아들여야겠지만, 우리가 원하는 Parquet의 장점을 취하기 위해서는 여러 가지 옵션을 조정하거나 직접 수정을 해야 합니다.VCNC 데이터팀에서는 저장 용량과 I/O 성능을 최적화하기 위하여 Parquet의Dictionary encoding (String들을 압축할 때 dictionary를 만들어서 압축하는 방식, 길고 반복되는 String이 많다면 좋은 압축률을 기대할 수 있습니다)Column pruning (필요한 컬럼만을 읽어 들이는 기법)Predicate pushdown, row group skipping (predicate, 즉 필터를 데이터를 읽어 들인 후 적용하는 것이 아니라 저장소 레벨에서 적용하는 기법)과 같은 기능들을 사용하기를 원했고, 이를 위해 여러 조사를 진행하였습니다.저장용량 줄이기102GB의 JSON 포맷 로그를 text그대로 gzip으로 압축하면 23GB가 됩니다. dictionary encoding이 잘 적용되도록 적절한 옵션 설정을 통해 Parquet로 저장하면 6GB로, 기존 압축방식보다 저장 용량을 74%나 줄일 수 있었습니다.val ndjsonDF = spark.read.schema(_schema).json("s3a://ndjson-bucket/2018/04/05") ndjsonDF. sort("userId", "objectType", "action"). coalesce(20). write. options(Map( ("compression", "gzip"), ("parquet.enable.dictionary", "true"), ("parquet.block.size", s"${32 * 1024 * 1024}"), ("parquet.page.size", s"${2 * 1024 * 1024}"), ("parquet.dictionary.page.size", s"${8 * 1024 * 1024}"), )). parquet("s3a://parquet-bucket/2018/04/05") 비트윈의 로그 데이터는 ID가 노출되지 않도록 익명화하면서 8ptza2HqTs6ZSpvmcR7Jww 와 같이 길어지기에 이러한 항목들이 dictionary encoding을 통해 효과적으로 압축되리라 기대할 수 있었고, Parquet에서는 dictionary encoding이 기본이기에 압축률 개선에 상당히 기대하고 있었습니다.하지만 parquet-mr 의 구현에서는 dictionary의 크기가 어느 정도 커지면 그 순간부터 dictionary encoding을 쓰지 않고 plain encoding으로 fallback하게 되어 있었습니다. 비트윈에서 나온 로그들은 수많은 동시접속 사용자들의 ID 갯수가 많기 때문에 dictionary의 크기가 상당히 커지는 상태였고, 결국 dictionary encoding을 사용하지 못해 압축 효율이 좋지 못한 상태였습니다.이를 해결하기 위해, parquet.block.size를 default 값인 128MB에서 32MB로 줄이고 parquet.dictionary.page.size를 default 값 1MB에서 8MB 로 늘려서 ID가 dictionary encoding으로만 잘 저장될 수 있도록 만들었습니다.처리속도 올리기저장용량이 줄어든 것으로도 네트워크 I/O가 줄어들기 때문에 처리 속도가 상당히 올라갑니다. 하지만 컬럼 기반 저장소의 장점을 온전하게 활용하기 위해서 column pruning, predicate pushdown들이 제대로 작동하는지 점검하고 싶었습니다.소스코드를 확인하고 몇 가지 테스트를 해 본 결과, Spark에서는 Parquet의 top level field에서의 column pruning은 지원하지만 nested field들에 대해서는 column pruning을 지원하지 않았습니다. 비트윈 로그에서는 nested field들을 많이 사용하고 있었기에 약간 아쉬웠으나 top level field에서의 column pruning 만으로도 어느 정도 만족스러웠고 로그의 구조도 그대로 사용할 예정입니다.Predicate pushdown도 실행시간에 크게 영향을 줄 거라 예상했습니다. 그런데 Spark 2.2.1기준으로 column pruning의 경우와 비슷하게, top level field에 대해서만 predicate pushdown이 작동하는 것을 확인할 수 있었습니다. 이는 성능에 큰 영향을 미치기에, predicate 로 자주 사용하는 column들을 top level 로 끌어올려 저장하는 작업을 하게 되었습니다. 여기에 추가로 parquet.string.min-max-statistics 옵션을 손보고 나서야 드디어 10~30배 정도의 성능 향상을 볼 수 있었습니다.매일 15분 정도 걸리던 "의심스러운 로그인 사용자" 탐지 쿼리가 30여초만에 끝나고, cs처리를 위해 한 사람의 로그만 볼 때 5분 정도 걸리던 쿼리가 30여초만에 처리되게 되었습니다.못다 한 이야기parquet.string.min-max-statistics 옵션과 row group skipping에 관해.Parquet 같은 포맷 입장에서 string 혹은 binary 필드의 순서를 판단하기는 어렵습니다. 예를 들어 글자 á 와 e 가 있을 때 어느 쪽이 더 작다고 할까요? 사전 편찬자라면 á가 더 작다고 볼 것이고, byte 표현을 보면 á는 162이고 e는 101이라 e가 더 작습니다. Parquet 같은 저장 포맷 입장에서는 binary 필드가 있다는 사실만 알고 있고, 그 필드에 무엇이 저장될지, 예를 들어 á와 e가 저장되는지, 이미지의 blob가 저장되는지는 알 수 없습니다. 그러니 순서를 어떻게 정해야 할지는 더더구나 알 수 없습니다.그래서 Parquet 내부적으로 컬럼의 min-max 값을 저장해 둘 때, 1.x 버전에서는 임의로 byte sequence를 UNSINGED 숫자로 해석해 그 컬럼의 min-max 값을 정해 저장했습니다. 이후에 이를 개선하기 위해 Ryan Blue가 PARQUET-686에서 parquet-format에 SORT_ORDER를 저장할 수 있도록 했습니다.여기에서 문제는 이전 버전과의 호환성입니다. SORT_ORDER가 없던 시절의 Parquet 파일을 읽으려 할 때, min-max 값을 사용해 row group skipping이 일어나면 query 엔진에서 올바르지 않은 결과가 나올 수 있으니, binary 필드의 min-max 값을 parquet-mr 에서 아예 반환하지 않게 되어있습니다.하지만 이는 우리가 원하는 동작이 아닙니다. 여기에 parquet.string.min-max-statistics option을 true로 설정하면, 이전처럼 binary필드의 min-max값을 리턴하게 되고 rowgroup skipping이 작동하여 쿼리 성능을 크게 올릴 수 있습니다.마치며Spark과 Parquet 모두 많은 사람이 사랑하는 훌륭한 오픈소스 프로젝트입니다. 또한 별다른 설정이나 튜닝 없이 기본 설정만으로도 잘 돌아가는 편이기 때문에 더더욱 많은 사람이 애용하는 프로젝트이기도 합니다.하지만 오픈소스는 완전하지 않습니다. 좋은 엔지니어링 팀이라면 단지 남들이 많이 쓰는 오픈소스 프로젝트들을 조합해서 사용하는 것에서 그치지 않고 핵심 원리와 내부 구조를 연구해가며 올바르게 활용해야 한다고 생각합니다. 기술의 올바른 활용을 위해 비트윈 데이터팀은 오늘도 노력하고 있습니다.
조회수 1416

[인공지능 in IT] 서로 다른 우리, 대화할 수 있을까?

설연휴 동안 그간 못 봤던 밀린 TV 프로그램들을 맘껏 즐기며 여유로운 시간을 보냈다. 그 중에서도 여러 분야의 전문가를 초빙해 특강을 해주는 tvN의 '어쩌다 어른'을 보기 시작했다. 몇 년 전 언어인문학을 주제로 한 조승연 작가님편을 보니 새삼 현재 대한민국이 처한 현실을 피부로 느끼게 되더라.< tvN>강연에서 가장 심도있게 다룬 부분은 대한민국 영어교육의 현실이다. 초등학교부터 영어 수업을 듣고, 심지어 말도 제대로 떼기 전인 유아기부터 영어를 주입시키는 것이 어느새 자연스러운 일이 되어버렸다. 하지만, 10년, 20년 이상 영어 교육을 받았는데도 막상 영어로 문서 작업을 하거나, 외국인이 길을 물어보면 식은땀을 흘리는 이유는 무엇일까? 어째서 한국에서는 영어를 제대로 하려는 노력보다, 영어를 아는 노력을 하고 있는 것일까?재미있는 사실은 우리만 영어를 배우려고 애먹는 것이 아니다. 미국인이 한국어를 배울 때에도 비슷한 현상을 겪는다. 강연 중 'FSI(The Foreign Service Institute)'에서 미국인들이 다른 나라 언어를 얼마나 공부해야 소통할 수 있는지에 대한 연구 자료를 공개했다. 언어별 Level 1부터 Level 5까지 다섯 가지 난이도로 구분 되어있고, 이에 따른 총 필요시간으로 구성되어 있는 연구에서, 한국어는 일본어, 중국어와 함께 소통하기 까지 총 2,200시간을 공부해야 하는 Level 5군에 속해 있었다.즉, 전세계 7,000여 개가 넘는 언어 중 한국어는 영어와 문장구조가 완전히 다르기 때문에, 24시간 내내 공부해도 90일 넘게 공부해야 한다는 것. 이렇듯 모국어가 아닌 다른 언어를 배우기 위해서는 어마어마한 시간과 노력이 필요하다. 만약, 단순히 언어를 알기 위해 배우는 것보다, 소통하기 위해 배운다면 흔히들 말하는 'ROI(Return on Investment)'를 더 높일 수 있자 않을까.출처: 동아일보소통을 위한 언어 학습은 비단 사람에게만 해당되는 것이 아니다. 기계와 사람의 소통 역시 요즘과 같은 인공지능 시대에서는 빼놓을 수 없는 부분이다. 몇 년 전부터 업계에서는 '챗봇(Chatbot)' 열풍이 불고있다. 챗봇은 대화(Chat)와 로봇(Robot) 두 단어를 합친 신조어로서, 각종 앱이나 웹을 기반으로 문자를 통해 사용자의 의도를 파악해 대화할 수 있는 인공지능 기계다. 여기에는 '자연어 처리(Natural Language Processing, NLP)', '자연어 이해(Natural Language Understanding, NLU)', '머신러닝(Machine Learning)' 등 수많은 기술이 접목되어 발전 중이다. 현재 챗봇은 나날이 진화하며, 텍스트를 텍스트로만 처리하는 것을 넘어, '음성으로 변환(Text-To-Speech, TTS)'시키거나, '음성을 텍스트로 변환(Speech-To-Text)'시키는 등 다양성에 있어 점점 넓은 범위에 적용되고 있는 추세다.< 출처: Understanding Natural Language Understanding, Bill MacCartney >글로벌 챗봇 시장은 매년 큰 폭으로 성장하고 있는 추세이며, 여러 사업 분야에 걸쳐 사용되고 있다. 북미의 시장조사기관 'Credence Research' 조사에 따르면, 글로벌 챗봇 시장은 2015년부터 2023년까지 연평균 35% 성장할 것으로 예상된다. IT솔루션 기업 'MindBowser'가 조사한 결과, 95%의 기업이 챗봇 활용성에 대해 긍정적인 반응을 보였으며, 고객응대(93%)부터, 마케팅(61%), 상품 주문(47%), 소셜 미디어(32%) 등 사업 분야에서 활용되는 용도 역시 다양한 것으로 밝혀졌다.챗봇은 어떠한 프로세스를 통해 실제로 작동하는지 살펴보기 위해서 사내 엔지니어의 도움을 받았다. 스켈터랩스에서 대화형 인공지능 프로젝트팀에 있는 정태형 엔지니어가 메신저를 통한 간단한 시범 사례를 스크린샷으로 찍어 보여주었다.< 인공지능 메신저 사례, 출처: 스켈터랩스 >여행지를 자동으로 추천해주는 엡에 적용할 수 있는 챗봇과의 대화다. 사용자가 "여행을 가고 싶다"고 말하자 자동으로 '카이트봇'이 반응하고, 여행 기간과 테마를 물어본다. 여기서 사용자가 "여행 기간"을 말하자 챗봇은 자동으로 '3월'과 '7일'을 인식, 이전 질문에서 대답하지 않은 테마에 대해 질문한다. 이렇게 사용자와 챗봇 사이에서 대화를 자연스럽게 주고 받을 수 있는 것은 대화의 구성 요소 중 '의도(Intent)', '개체(Entity)', '맥락(Context)'이 중요한 역할을 한다. 이를 간단히 살펴보도록 하자.의도(Intent)는 사용자가 어떠한 의도로 대화를 하는지를 의미한다. 위 스크린샷의 경우, 여행을 가는 것'이 의도라 할 수 있다. 예를 들어, "여행 가고 싶어"가 아닌 "여행 가볼까?"로 입력하더라도 - 미리 여행을 가는 것에 대한 자연어 기반 패턴이 'Intent Classifier'에 입력되어 있는 상태라면 - 이를 '사용자가 여행을 가고 싶구나'라는 의도로 이해할 수 있는 것이다.개체(Entity)는 사용자의 의도 중에서 실체가 될 수 있는 변수를 말한다. 개체는 사용자가 입력한 문장에서 특정한 변수가 달라질 때 사용된다. 위 스크린샷의 경우, '3월 3일', '해변', '일주일' 등과 같이 주로 명사 형태로 구성된 문장에 들어가는 구성 요소를 말한다.문맥(Context)은 이전 대화를 자연스럽게 이어갈 수 있도록 처리할 수 있는 기능이다. 예를 들어, 사용자가 챗봇에게 "가수 빅뱅의 프로필을 검색해달라"고 요청했다. 그리고 빅뱅의 노래를 듣기 위해 "거짓말 틀어 줘"라고 명령하면, 기존에 빅뱅이라는 가수에 대해 대화하고 있던 문맥을 인식해 God의 거짓말이 아닌 빅뱅의 거짓말을 재생하는 것이다.이 외에도 챗봇에는 '말뭉치(Utterance)', '시나리오(Scenario)', '슬롯채우기(Slot Filling)' 등 다양한 구성요소를 통해 대화를 이어나갈 수 있다. 물론, 아직 100% 인간과 대화하는 기술까지 이르지는 못했다. 하지만, 우문현답하지 않고 사용자 의도를 정확하게 파악하는 수준에 이르러 생활에 편의성을 제공하고 있다.한국어의 경우 언어의 난이도 때문에 국내 기업은 물론 많은 글로벌 IT 기업도 아직 완벽한 수준에 도달하지 못했다. '잘 한다'라는 말만 하더라도 '훌륭하게 하다', '만족할 만하다', '자주 하다' 등의 긍정적인 표현이 있는가 하면, '잘 하는 짓이다' 등의 부정적인 표현인 경우도 흔하기 때문이다. 결국 챗봇도 기계이기 때문에, 여러가지 문장과 상황을 학습시켜 한국어 성능을 향상시켜야만 한다.다시 '어쩌다 어른'으로 돌아가보자. 강연을 마무리할 즈음 조승연 작가는 이렇게 말한다."영어도 결국 언어의 한 종류, 영어를 쓰는 사람들도 우리와 같은 사람, 우리처럼 희로애락을 느끼는 인간입니다. 기계와 얘기하기 위해 법칙에 맞춰 말해야 하는 것이 아니라 그 사람과 감정을 통하게 해주는 어떤 도구입니다."여전히 우리는 챗봇이라는 기계와 소통한다기 보다, 일방적으로 질문을 던지고, 챗봇은 미리 입력되어 있는 규칙 안에서만 답한다. 학습을 통해 수많은 데이터가 축적된다 하더라도, 아직까지 언어를 통해 전달되는 인간의 감정을 완벽히 이해하기에는 부족한 것이 사실이다. 과연 기계가 '법칙'에 맞춰서 말해야 하는 것 이상을 넘어서는 순간이 올까? 우리는 그 순간을 찾아 지금도 노력하고 있는지 모른다.이호진, 스켈터랩스 마케팅 매니저조원규 전 구글코리아 R&D총괄 사장을 주축으로 구글, 삼성, 카이스트 AI 랩 출신들로 구성된 인공지능 기술 기업 스켈터랩스에서 마케팅을 담당하고 있다#스켈터랩스 #기업문화 #인사이트 #경험공유 #조직문화 #인공지능기업 #기술기업

기업문화 엿볼 때, 더팀스

로그인

/