스토리 홈

인터뷰

피드

조회수 2089

챗봇과 인공지능 머신러닝 ㅡ Part 1/2

스타워즈를 보신 분이라면 거기에 나오는 난쟁이 로봇 R2D2와 키다리 로봇 C3P0를 아실 것이다. 친근한 R2D2는 전자음을 조정해 인간과 대화를 하며 주로 말 잘하고 박식한 로봇인 C3P0가 통역을 해준다.이런 충실하면서 똑똑한 친구들이 옆에서 항상 나를 도와준다면 어떨까? 정말 좋을 것이다. 만약 매일 보는 스마트폰 안에서도 나의 질문에 답해주는 이런 고마운 친구들이 있다면 얼마나 좋을까? 이런 저런 생각을 하다보면 우리는 대화형 로봇의 필요성을 느낀다.챗봇(Chatbot)이란?챗봇의 정의는 “대화형 인터페이스 상에서 규칙 또는 지능으로 유저와 소통하는 서비스”이다. 이 말을 하나하나 풀어보자.먼저, 대화형 인터페이스란 뭐지? 어렵다. 쉽게 설명해 보자. 인터페이스는 사람과 컴퓨터를 연결하는 장치라고 한다. 역시 어렵다. 아! 그냥 스마트폰 앱으로 보면 된다. 그럼 소통한다는 말은 대화한다는 것이므로 스마트폰 앱에서 일방향이 아닌 양방향이 가능하다는 얘기다. 어! 이상하다. 양방향이라면 나의 말에 응대하는 로봇은 뭐로 움직이는 거지? 궁금하다. 누가 일정한 규칙으로 만들어 논건지 아니면 우리처럼 지능이 있는 건지. 지능이 있다면 그런 지능은 뭐지? 점차 우리는 자연스럽게 인공지능에 다가간다.인공지능(Artificial Intelligence)이라는 용어는 1956년 미국 다트머스의 한 학회에서 존 매카시가 처음 사용했다고 한다. 원래 인공지능은 소프트웨어인 정신을 말하고 로봇은 하드웨어인 육체를 말하는 것이지만 정신없이 육체가 존재할 수 없는 것처럼 로봇을 얘기하면 당연히 인공지능은 따라간다.학자들은 인공지능을 강(强)인공지능과 약(弱)인공지능으로 구분한다. 간단히 얘기하면 강인공지능이란 자의식이 있는 인간에 가까운 지능이고 약인공지능은 자의식이 없다. 자아가 없으며, 명령받은 일만을 수행한다. IBM의 왓슨(Watson), 작년에 인공지능의 붐을 가져온 구글의 알파고(Alpha-GO) 등은 모두 약인공지능이다. 이런 인공지능을 구현하는 기술은 무엇인가? 바로 기계한테 학습을 시키는 머신러닝(Machine Learning)이다.1959년 아서 사무엘은 머신러닝을 "기계가 일일이 코드로 명시하지 않은 동작을 데이터로 부터 학습하여 실행할 수 있도록 하는 알고리즘을 개발하는 연구 분야"라고 정의했다. 여기서 학습이란, 입력 값을 받아 결과 값을 내는 모델을 만드는 표현과 표현을 통해 주어진 업무가 얼마나 잘 수행됐는지 알아보는 평가, 그리고 평가에서 설정한 기준을 찾는 최적화로 구성된 일련의 과정을 말한다. 중요한건 우리가 시키지 않은 일도 학습에 의해 자율적으로 처리한다는 것이다. 정말 신기하지 않은가?이제 챗봇이 뭔지 감이 잡힌다. 스마트폰 앱상에 존재하는 로봇인데, 물론 육체는 화면의 아이콘으로 밖엔 안보이지만 인공지능을 가지고 머신러닝에 의해 동작을 하면서 우리와 대화를 하는 그분. 그렇다면 이제 남은 건 이분의 지능이 어느 정도인지 또 얼마나 일을 잘하는 지로 판가름 난다.우리는 평생 공부를 한다. 이제는 학교를 졸업하고 나서도 항상 배워야 한다. 학습이 없다면 지능도 없다. 학습은 일일이 지도받는 지도학습과 알아서 공부하는 자율학습이 있다. 알아서 공부하려면 먼저 머리에 지식이 많아야 한다. 역시 기계도 사람과 비슷하게 배운다.  다음시간엔 챗봇에게 학습을 시켜 지능을 가지게 하는 방법에 대해 알아본다.> Part 2에서 계속
조회수 1071

하나부터 열까지 모두 알려주겠다! Scatter 계정 만들기 (feat. HexBP 연동하기)

스캐터(Scatter)는 암호화폐 지갑 계정에 대한 신원인증을 대행해주는 일종의 신원인증 프로그램으로, 별도의 보팅포털에 접속해서 신원인증을 통해 로그인을 도와주는 크롬의 확장 프로그램입니다.스캐터를 사용하게 되면, 기존에 여러 지갑 및 사이트로 부터 EOS 프라이빗 키를 부여 받아야 했던 번거로움 없이, 한번만 등록해놓으면 다양한 사이트에서 스캐터 계정 하나로 자신의 EOS 계정을 증명할 수 있게 됩니다.이러한 스캐터를 사용하는 방법을 지금 부터 알아보겠습니다.Step 1. Scatter 설치 및 계정 생성Scatter에서 크롬 확장 프로그램을 다운로드하여 설치하셔야 합니다.설치 후 크롬 브라우저에 설치된 Scatter 아이콘을 누르시면 다음과 같은 화면이 나타납니다.새로운 비밀번호 (최소 8글자)를 입력하시면 됩니다.비밀번호 입력 후 Create New Scatter 버튼을 누르세요.그럼 아래와 같이 12단어가 표시된 화면이 나타납니다. 바로 단어들을 복사 혹은 화면 캡처를 하여 보관해야 합니다.( * 저장하지 않은 채 다른 창을 누르시게되면 해당 화면이 사라지게 되니 꼭 바로 저장하셔야 합니다.)이 단어들은 나중에 비밀번호를 잃어버렸을 때 필요합니다.다 복사를 하셨으면 [ I wrote it down]을 눌러주세요.그 다음 화면에서 백업을 하실 지, 그냥 넘기실 지 선택하셔야 합니다.선택하시면 다음화면으로 넘어가게 됩니다.이제 더 편리하게 사용할 수 있도록 한국어 설정으로 바꿔 볼 거에요!우측 상단의 톱니바퀴 모양을 누르신 후[Language]-한국어 선택 -[Change Language] 차근차근 클릭하여진행하시면 됩니다.짜잔! 이제 한국어 버전으로 사용할 수 있습니다.이제부터 Scatter를 통해 자신의 EOS 프라이빗 키를 등록하셔야 합니다.왼쪽 상단의 [ < ]뒤로가기 버튼을 누르시면 다음과 같은 화면이 나옵니다.여기서 두번째 줄에 보이는 키 쌍(Key pairs)을 선택합니다.우측 상단의 [신규 생성]버튼을 클릭 하셔서 계정을 생성 하셔야 합니다.버튼을 누르시면 아래와 같은 화면을 확인하실 수 있습니다.이는 ‘현재 등록이 되어 있지 않다’는 것을 의미합니다.프라이빗키 항목에 자신의 EOS 프라이빗키를 넣고이름은 영어나 숫자를 이용하여 자유롭게 이름을 정하시면 됩니다.*프라이빗 키를 입력하면 퍼블릭 키는 자동으로 입력됩니다.*반드시 키 쌍 생성 버튼이 아닌 저장 버튼을 누르셔야 합니다.정상적으로 등록이 완료되면 다음과 같은 화면을 확인 하실 수 있습니다.다들 잘 따라오셨나요?만약 이 절차를 진행하셨음에도 등록이 안되었다면 계정이 EOS에 등록이 되지 않은 경우입니다.Step2 : Scatter 설정하기이제 등록된 Scatter 계정을 통해 HEX BP 사이트의 투표 시스템과 연동하는 방법을 알아보겠습니다.Scatter의 첫 화면으로 돌아가서 [톱니바퀴]를 선택합니다.해당 버튼을 누르시면 다음과 같은 화면이 나타납니다.[네트워크]를 선택합니다.해당 버튼을 누르시면 아래와 비슷한 화면이 나타납니다.이제 다시 우측 상단의 [신규 생성] 버튼을 누릅니다.해당 버튼을 누르면 네트워크 정보를 입력해야 하는 화면이 나옵니다.* 이름 : eosnet.hexlant.Io* https 선택* 도메인 혹은 IP 주소 : 목록 중에 선택* 포트 : 80* 체인 ID : aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906복사하여 붙여넣기모두 정확하게 입력 하셨으면 저장 버튼을 눌러주시기 바랍니다.이제 등록한 Chain을 계정에 연결해야 합니다![신원인증 ID]를 눌러주세요그 다음 [신규 생성]을 클릭 합니다.EOS Mainnet을 설정 한 후에 자신의 계정을 선택합니다.모두 선택하셨으면 [가져오기]를 누릅니다.[가져오기] 버튼을 누르신 후 잠시 기다리시면다음과 같은 화면이 나타납니다.이때 acticve 권한을 클릭 후 [선택한 계정 사용] 버튼을누르시기 바랍니다.*아래 개인 정보 입력하는 부분은 옵션이기 때문에 굳이 입력하지 않으셔도괜찮습니다. 모두 입력 하셨으면 [저장] 버튼을 눌러주시기 바랍니다.이제 스캐터 새 계정이 성공적으로 만들어졌습니다. 짝짝짝Step 3 : 투표하기[Login] 눌러서 Scatter 로그인 하기2. [신원인증 ID 선택]-[수락] 클릭하기3. Log out으로 바뀐 화면을 확인하실 수 있습니다.4. 투표를 하기 위해선 [Vote] 버튼을 누르셔야 합니다.5. Vote 버튼을 누르시면 체크박스가 생성됩니다! 이제 21명의 BP가 되길 원하는 후보자를 선택하시면 됩니다.누르시면 아래부분에 선택한 BP 후보자들을 확인하실 수 있습니다.후보자를 다 선택하셨다면 [Done] 버튼을 눌러 투표를마무리 해주시면 됩니다!6. [Done] 을 누르시면 마지막으로 Scatter 화면이 뜹니다. 여기서 [Accept] 버튼을 누르시면 됩니다.자 이제 투표도 모두 완료되었습니다!#헥슬란트 #HEXLANT #블록체인 #개발자 #개발팀 #기술기업 #기술중심 #Scatter
조회수 1561

파이썬의 개발 “환경”(env) 도구들

안녕하세요. 스포카 프로그래머 홍민희입니다.파이썬 패키징 생태계에서 개발 환경을 구성하기 위해 널리 쓰이는 virtualenv나 pyvenv, virtualenvwrapper 같은 각종 도구가 왜 필요한지 (또는 자신에게는 큰 도움이 안 되는지) 알려면 그 이전의 파이썬 라이브러리 배포 방식에 대한 이해가 많은 도움이 됩니다. 여기서는 필요한 몇 가지 역사적 사실과 파이썬 패키징 개념 중 현재의 생태계 이해에 필요한 것들을 위주로 정리하고, 최종적으로 각자의 필요에 따라 어떤 도구를 활용하면 될지 지침을 제안합니다.sys.path패키징이고 뭐고 아무것도 없던 90년대 말에는 라이브러리 소스 코드 파일들을 타르볼(tarball)로 압축해서 배포했습니다. 쓰는 사람은 그걸 자신의 애플리케이션 소스 트리 안에 풀어서 사용했습니다.파이썬에는 지금도 sys.path라는 인터프리터 전역적인 상태가 존재합니다. PATH 환경 변수가 실행 바이너리를 찾을 디렉터리 경로들의 목록인 것과 비슷하게, sys.path도 import foo를 하면 foo.py (또는 foo/__init__.py) 파일을 찾을 디렉터리 경로들의 목록을 담습니다. 그리고 기본 동작으로 그 목록의 맨 처음에는 현재 디렉터리(./)가 들어갑니다. 따라서 라이브러리 타르볼을 애플리케이션 소스 트리에 풀어두면 import해서 쓸 수 있습니다.하지만 자신이 작성한 애플리케이션 코드와 남이 작성한 라이브러리 코드를 같은 소스 트리에서 관리하는 것은 여러모로 불편합니다. 따라서 라이브러리는 애플리케이션 소스 트리와는 별도의 디렉터리(예: ../libs/)에 풀어서 관리하고, 애플리케이션 소스 코드 맨 위에 아래와 같이 써두는 패턴이 많았습니다.import sys sys.path.append('../libs') 또는 sys.path를 소스 코드를 건드리지 않고 조작하기 위해 PYTHONPATH 환경 변수를 활용하는 경우가 많았습니다.세기말, 파이썬 1.5를 쓰던 때의 이야기입니다.site-packages새 천 년이 밝았고 파이썬 2.0이 나왔습니다. 표준적인 라이브러리 배포 방식 및 설치 방식이 제안되었고, 표준 라이브러리에 distutils도 들어왔습니다. (지금도 setuptools는 distutils에 의존하고, pip는 setuptools에 의존합니다.) 제안된 방식은 이랬습니다.애플리케이션 코드가 아닌 라이브러리 소스 코드는 모두 /usr/local/lib/pythonX.Y/site-packages/ 디렉터리 안에 둡니다. X.Y는 파이썬 인터프리터 버전이고, 경로는 인터프리터를 빌드할 때 (./configure) 정합니다. 데비안 계열은 site-packages 대신 dist-packages라는 이름으로 바꿔서 빌드하는 등, 파이썬 인터프리터의 설치 방식에 따라 달라집니다. 어떻게 정하든 이를 site-packages 디렉터리라고 부릅니다. 파이썬 인터프리터를 빌드할 때 경로가 결정되므로, 파이썬 인터프리터 별로 각자의 site-packages 디렉터리를 갖게 됩니다. (한 시스템에서 여러 파이썬 버전을 설치했을 때 pip 역시 pip2.7, pip3.6 등과 같이 버전 별로 명령어가 생기는 것도 같은 이유입니다.)기본적으로 sys.path 목록에는 맨 앞에 현재 위치(./), 뒤쪽에는 site-packages 경로가 들어있습니다. import를 하면 현재 위치에서 찾고, 없으면 site-packages를 찾아본다는 뜻입니다.표준 라이브러리의 distutils.core.setup() 함수는 라이브러리 파일들을 시스템의 site-packages 디렉터리에 복사해주는 함수입니다. 라이브러리 타르볼 파일 맨 바깥에는 이 함수를 이용해 라이브러리를 시스템 site-packages에 설치해주는 스크립트를 setup.py라는 파일명으로 포함하는 관례가 있었습니다. pip 같은 게 없던 때에는 라이브러리 타르볼을 받아서 푼 다음 python setup.py install 명령을 실행하는 것이 일반적인 라이브러리 설치법이었습니다. 지금도 pip는 *.whl 파일이 아닌 *.tar.gz/*.zip 파일인 패키지를 설치할 때 내부적으로 python setup.py install 스크립트를 실행합니다.참고로 이때 정립된 파이썬 패키징 표준은 리눅스에서 쓰이는 dpkg나 RPM 같은 일반적인 패키징 방식을 의식하며 만들어졌습니다.1 당시는 도커는 커녕 가상화 자체가 보편적이지 않던 때로, 한 시스템에 여러 애플리케이션을 함께 설치해서 쓰는 멀티테넌시 환경이 일반적이었기 때문입니다.workingenv파이썬으로 작성한 애플리케이션 여럿이 한 시스템에 설치되면 공통으로 의존하는 라이브러리의 버전을 결정하는 게 문제가 됩니다. A 애플리케이션은 foo >= 1.0.0, < 2>에 의존하고 B 애플리케이션은 foo >= 1.5.0에 의존하면 시스템에 설치할 수 있는 foo의 버전은 >= 1.5.0, < 2>으로 한정됩니다. 만약 C 애플리케이션을 설치하려는데 foo > 2.0.0에 의존한다면, A나 C 중 하나는 포기해야 합니다.시스템에 파이썬 애플리케이션을 단 하나만 설치한다 해도, 설치하는데 시스템 관리자 권한이 필요하다는 것도 문제였습니다. 일반적으로 site-packages 디렉터리는 시스템 관리자만 수정할 수 있고 나머지는 읽기만 가능한 /usr 아래 어딘가로 정해졌기 때문입니다. 이를 우회하려고 사용자가 시스템에 설치된 파이썬 인터프리터를 쓰지 않고 직접 파이썬 인터프리터를 빌드해서 사용하는 편법도 쓰였습니다.이런 문제를 해결하기 위해, 애플리케이션·프로젝트마다 별도의 site-packages 디렉터리를 두는 방식이 제안됐습니다. 나중에 virtualenv을 만들게 되는 이안 비킹이 그 전신인 workingenv를 만들어 이 아이디어를 실현했습니다. 현재의 virtualenv 사용 방식은 workingenv에서 만들어진 것입니다.애플리케이션마다 별도의 “환경”(env)을 만듭니다.애플리케이션을 실행하기 전에 우선 그 “환경”을 “활성화”(. bin/activate 또는 Scripts\activate.bat)합니다.workingenv가 만들어주는 활성화 스크립트는 PATH와 PYTHONPATH 환경 변수를 재정의하여 시스템에 설치된 파이썬 인터프리터의 실행 바이너리 디렉터리 및 site-packages 디렉터리를 가리키는 대신, “환경” 내의 bin/ 및 site-packages 디렉터리를 바라보도록 해줍니다. 이안 비킹은 이렇게 분리된 실행 파일들(bin/)과 site-packages 등을 묶어서 “환경”이라고 명명했는데, workingenv 이후로 파이썬 패키징 및 배포 분야에서 이 용어가 정착됩니다.최근에 만들어진 신생 언어의 패키지 관리자는 대부분 파이썬과 달리 애플리케이션·프로젝트마다 별도의 환경을 두고 설치되는 경우가 많습니다. 예를 들어 npm은 -g 옵션을 일부러 켜지 않는 한 현재 디렉터리를 기준으로 ./node_modules 디렉터리에 라이브러리를 설치하게 되어 있고, 별도의 “활성화” 없이도 노드 인터프리터가 해당 경로에서 라이브러리를 찾습니다. 하지만 파이썬의 패키징 표준은 앞서 언급한 것처럼 멀티테넌시 환경이 일반적이었던 시대에 만들어졌고, 또 많은 라이브러리가 실행 파일도 함께 제공하기 때문에2 PYTHONPATH 뿐만 아니라 PATH 환경 변수도 재정의해야 해서 activate 과정이 필요합니다.workingenv는 파이썬 웹 프로그래머 사이에서 빠르게 퍼지기 시작했습니다. 웹 애플리케이션은 정통적인 CLI 및 GUI 애플리케이션과 달리 FHS 표준 같은 것에 크게 구애될 필요가 없었고, 웹 애플리케이션의 배포도 점차 가상화 기술을 통해 완전히 격리된 시스템에 설치되는 식으로 보안 문제에서 많이 자유로워졌기 때문입니다.무엇보다 workingenv는 프로그래머가 여러 프로젝트를 동시에 작업하는 경우 골치 아팠던 라이브러리 버전 충돌 문제를 우회했기 때문에, 배포 도구보다는 개발 도구로 정착되는 면이 컸습니다.virtualenv이안 비킹은 PYTHONPATH를 조작하여 별도의 site-packages 공간을 두는 workingenv의 방식이 복잡하게 패키징된 기존 라이브러리 및 프로젝트에서 호환되지 않는 문제로 골머리를 썩이다, 아예 PYTHONPATH를 이용하지 않는 방식으로 새 도구를 만듭니다.새로운 방식은 아예 파이썬 인터프리터 실행 바이너리를 복사한 뒤, sys.path 기본값에 박힌 시스템 site-packages 경로를 환경 내 site-packages 경로로 바꿔버리는 것이었습니다. 이러한 동작 원리의 차이는 이용자 입장에서 크게 중요한 것은 아닙니다.하여튼 이안 비킹은 virtualenv라는 이름으로 새 도구를 만들었고, workingenv를 빠르게 대체했습니다.virtualenvwrapper앞서 언급한 것처럼, workingenv와 그 후계자인 virtualenv는 저자의 의도와 무관하게 애플리케이션 배포보다는 개발 용도로 더 널리 쓰입니다. 파이썬 프로그래머가 새로운 프로젝트를 시작할 때는 항상 “환경”도 생성합니다. 또 개발을 시작할 때마다 “활성화” 과정도 거칩니다. 너무나 반복적이기 때문에 당연히 이를 자동화하는 도구도 만들어졌습니다. virtualenvwrapper는 바로 그런 목적으로 만들어진 bash/zsh/fish 스크립트 모음입니다.여러 단축 명령을 제공하지만, 핵심 기능은 다음의 두 가지입니다.A라는 프로젝트 작업을 시작할 때마다 cd ~/projects/a; . .venv/bin/activate라고 쳐줘야 했던 것을 workon a 명령으로 줄여줍니다.프로젝트 디렉터리마다 .venv/ 또는 .env/ 등의 이름으로 환경 디렉터리를 생성해두고 버전 관리 시스템에서는 제외되도록 .gitignore 목록에 해당 디렉터리를 넣었어야 했습니다. 예를 들어 ~/projects/a/.venv/, ~/projects/b/.venv/ 같은 식이었습니다.virtualenvwrapper를 쓰면 환경 디렉터리들을 일정한 위치로 모아줍니다. 위치는 기본값이 없으며 virtualenvwrapper 설치할 때 WORKON_HOME 환경 변수를 통해 입맛대로 정할 수 있습니다. 예를 들어 WORKON_HOME을 ~/.virtualenvs/ 디렉터리로 정했다면, 프로젝트별 환경은 ~/.virtualenvs/a/, ~/.virtualenvs/b/ 같은 식으로 저장됩니다.pyvenv파이썬 3.3부터는 virtualenv가 아예 파이썬에 내장됐습니다. 환경을 만드는 명령어는 virtualenv가 아닌 pyvenv로 좀 다르지만, 그 이후의 과정은 같습니다. 파이썬 3만 사용한다면 이제 virtualenv를 따로 설치할 필요가 없어진 것입니다.참고로 아래에서 설명할 pyenv와는 다른 도구입니다. 철자의 “v”에 주의해주세요.pyenv애플리케이션을 개발할 때는 하나의 파이썬 버전을 정하면 되지만, 라이브러리는 여러 파이썬 버전과 호환되어야 합니다. 그러다 보니 라이브러리 개발자는 여러 버전의 파이썬을 시스템에 동시에 설치할 필요가 있습니다. 데드스네이크스 PPA나 데드스네이크스 홈브루 탭 같은 것을 이용해서 설치할 수도 있지만, 보통은 pyenv를 많이 씁니다.pyenv는 동시에 여러 버전의 파이썬을 시스템에 설치해주며, 이렇게 설치된 파이썬은 시스템의 패키지 시스템(데비안·우분투의 APT나 맥OS의 홈브루 등)을 통해 설치되는 것이 아니라, pyenv가 다운로드와 빌드 및 설치를 직접 하여 별도로 관리합니다. 설치된 파이썬들은 PEP 394에 따라 일정한 형식으로 이름지어진 명령어(예: python2.7, python3.6)로 실행할 수 있게 됩니다.또한, 여러 파이썬 버전 중에 하나의 시스템 기본 파이썬 버전도 선택 가능하며, 특정 프로젝트 디렉터리 안에서만 기본 파이썬의 버전이 달라지게 할 수도 있습니다.pyenv-virtualenvpyenv가 여러 파이썬 버전을 동시에 설치해주기는 하지만, 그렇다고 자동으로 site-packages가 프로젝트마다 격리되는 것은 아닙니다. 예를 들어 pyenv로 파이썬 3.6을 설치한 뒤, 파이썬 3.6으로 두 프로젝트를 한 시스템에서 개발할 경우 두 프로젝트는 시스템 site-packages를 함께 쓰게 됩니다.따라서 pyenv를 쓰더라도 virtualenv는 따로 써야 하는데, 따로 사용할 수도 있지만 pyenv-virtualenv를 쓰면 pyenv virtualenv 명령으로 프로젝트에 쓸 파이썬 버전 지정과 가상 환경 생성을 한 번에 할 수 있게 됩니다.비슷하게 pyenv와 virtualenvwrapper를 통합해주는 pyenv-virtualenvwrapper 같은 도구도 있습니다.마치며여러 파이썬 개발 환경 관리 도구를 소개했지만, 여기 있는 모든 도구를 꼭 써야 하는 것도 아니고, 가장 최근에 나온 도구로 하루빨리 갈아타야 하는 것도 아닙니다. 글을 쓴 저 자신도 pyenv 같은 도구가 나온 지 몇 년이나 지났고 주변에서 쓰는 사람이 많음에도 쓰지 않고 있습니다. virtualenvwrapper를 대체하는 Pipenv 같은 실험적인 방식3도 생겨나고 있지만, 어느 쪽이든 동시에 여러 파이썬 프로젝트를 작업하는 사람이 아니라면 굳이 쓸 필요가 없는 도구입니다. 각자의 용도에 따라 필요한 수준의 도구를 이용하면 됩니다. 2017년 10월 현재, 아래의 지침으로 정리할 수 있겠습니다.파이썬 프로그래머가 아니지만, 파이썬 애플리케이션을 설치해서 이용합니다.시스템에서 제공하는 패키지 관리자(APT나 홈브루 등)를 통해 애플리케이션을 설치하세요.파이썬 프로그래머가 아니지만, 파이썬 애플리케이션을 유난히 많이 이용합니다.pipsi를 이용해 파이썬 애플리케이션을 설치하는 것을 권합니다.파이썬 프로그래머이고, 하나의 애플리케이션을 개발합니다.파이썬 3.3 이상을 이용할 경우 pyvenv로 개발 환경을 만들어서 개발하세요. 그 이전의 파이썬 버전을 이용할 경우 virtualenv를 활용하세요.파이썬 프로그래머이고, 여러 애플리케이션을 개발합니다.virtualenvwrapper를 활용하세요.파이썬 프로그래머이고, 여러 애플리케이션을 다양한 파이썬 버전으로 개발합니다.pyenv-virtualenvwrapper를 활용하세요.파이썬 프로그래머이고, 라이브러리를 개발합니다.pyenv와 tox를 활용하세요.파이썬으로 만든 애플리케이션을 distutils를 통해 패키징한 뒤, RPM 기반의 리눅스 배포본 용으로 python setup.py bdist_rpm 명령을 통해 *.rpm 파일을 제공하기도 했습니다. 이를 통해 애플리케이션을 설치할 경우, 각 파일들은 리눅스 FHS 표준과 해당 시스템 설정에 따라 흩어지게 됩니다. ↩예를 들어 파이썬에서 가장 많이 쓰이는 국제화 라이브러리인 바벨은 pybabel 명령어를, 구문 강조 라이브러리인 파이그먼츠는 pygmentize 명령어를, 장고는 django-admin 명령어를 제공합니다. ↩저는 2017년 4월에 한 번 써보았으나, 아직은 실무에서 쓰기에는 이르다는 결론을 내렸습니다. 이에 관한 그때의 제 감상은 별도의 글로 다루었습니다. ↩#스포카 #파이썬 #개발팀 #개발자 #인사이트 #후기 #일지
조회수 3045

[어반베이스 인턴일기] 전공의 벽을 뚫어낸 능력자들

                                                      ‘전공무관’. 많은 채용 사이트에서 볼 수 있는 이야기죠. 하지만 채용공고만 그렇지, 막상 개발이라면 컴퓨터 공학을 전공해야 할 것 같고, 마케팅이라면 경영을 전공해야 할 것만 같습니다. 하지만 어반베이스의 개발 인턴들은 컴퓨터공학을 전공하지 않았고, 마케팅 인턴도 경영학을 전공하지 않았다는 사실! 우리는 어떻게 어반베이스를 알게 되어 어반베이스를 선택하게 되었을까요? 이제 들어온 지 한 달, 타운홀 미팅을 통해 정식으로 인사도 드렸으니 진정한 어반베이스의 식구가 되었습니다. 한달 간 느낀 인턴들의 솔직한 이야기를 만나보세요!※ 타운홀이란 ? 매달 1회 전직원이 모여 자유로운 주제로 소통하고 네트워킹하는 어반베이스만의 토론 문화 Pt 0. 자기 소개 및 하는 일 왼쪽부터 민진, 수민, 윤아마케팅부문 인턴 _ 민진 (컨텐츠 제작)건축공학을 전공하고 마케팅 부문 인턴이 되었다.어반베이스의 SNS들을 관리하고, 그에 맞는 컨텐츠를 제작, 그리고 이번에 열리는 어반스니커즈 컨퍼런스의 진행을 돕고 있다.개발부문 인턴 _ 수민 (3D 도면변환)건축학을 전공하고 개발부문 인턴이 되었다. 지금은 3D로 변환된 도면을 산업에서 쓸 수 있도록 다양한 3D 포맷으로 바꾸는 일을 한다. 개발부문 인턴 _ 윤아 (머신러닝)생체의공학을 전공하고 개발부문 인턴이 되었다.공간을 찍으면 공간이 어느 곳인지 인식하여 분류해주는 작업이다. 머신러닝과 딥러닝을 사용해서, 연령, 성별, 취향 등으로 공간을 세분화하여 그 공간에 맞는 제품을 추천해주는 시스템까지 계획하고 있다Pt 1. 선택Q. 어반베이스의 인턴 셋은 모두 전공과 다른 길을 가고 있네요. 어떻게 선택하게 된 길 인가요?전공과 맞지 않음을 깨달은 인턴 3人수민 : 전공이 건축이잖아요. 그런데 설계에 대한 회의가 들었어요. 그리고 VR에 관심이 생겼고, 그래서 프로그래밍을 배우게 됐어요.윤아 : 생체의공학과는 주로 배우는 분야가 하드웨어 쪽에 가까워요. 근데 저는 하드웨어 쪽은 잘 안 맞는 것 같더라고요. 전자공학과를 복수 전공하면서 프로그래밍 수업을 듣다가 프로그래밍을 이용한 데이터 분석에 흥미를 갖게 됐어요. 민진 : 취직 준비를 하면서 느꼈는데, 건축업계 자체가 굉장히 폐쇄적이고 수직적이고 보수적인 문화를 가지고 있더라고요. 그런 곳에서 잘 적응하지 못할 것 같아 건축이라는 전공을 살려 할 수 있는 다양한 길을 찾아 봤고, 그런 과정 중에 어반베이스를 알게 됐어요.Q. 그렇다면 왜 어반베이스를 선택했나요? 윤아 : 데이터 사이언스 쪽으로 일자리를 찾다가 알게 됐어요. 수치나 텍스트 데이터를 사용해서 분석하는 공부를 많이 해서, 이미지 데이터를 사용하는 분야도 배우고 싶었는데, 어반베이스에서 그런 일을 하더라구요.수민 : VR에 관심이 있었고, 회사가 하는 일이 건축 전공이라면 잘 맞을 것 같아서 선택했고, 와서 겪어보니 실제로도 그런 것 같아요. 채용공고나 블로그에서 봤던 회사의 복지나 비전도 선택에 큰 영향을 미쳤죠. 민진 : 건축을 베이스로 하는, 4차 산업혁명의 흐름을 직접 느낄 수 있는 회사에서 일을 하고 싶었어요. 그래서 무모하지만 과감하게 마케팅 팀에 지원을 했습니다. 수민님에게 큰 영향을 주었다는 어반베이스의 꿀복지!Q. 대기업이 아닌 스타트업을 생각했던 이유가 있나요? 윤아 : 대기업의 획일화 된 채용 시스템이 싫었어요. 딱딱하고, 틀에 박혀있는 그런 형식들이요.민진 : 저두요. 그리고 저는 스타트업에서 일을 하면 바로 실무를 할 수 있다고 해서 욕심이 났어요. 바로 일을 해보고 싶었거든요.Q. 전에 일을 하신적이 있나요? 실제로 일을 해보니 어떤가요?수민 : 실무를 하는 것은 처음이에요. 저는 3D로 변환된 도면을 산업에서 쓸 수 있도록 다양한 3D 포맷으로 바꾸는 일을 해요. 설계할 때는 3D 툴을 직접 다루는 입장이었는데 지금은 파일만 다루니 생소하긴 하네요. 부담되기도 하지만, 사람들에게 많이 물어보거나 정보를 알아서 흡수하려고 해요. 3D 도면변환을 담당하고 계신 수민님윤아 : 마찬가지로 실무는 처음이에요. 저는 머신러닝 쪽인데, 쉽게 말해서 공간을 찍으면 공간이 어느 곳인지 인식하여 분류해주는 작업이에요. 일단 아직은 배우는 중이라 그런지 일이 재미있어요. 시간이 빨리 가는건 재밌다는 거 아닐까요? 사실 사수가 있을 줄 알았는데 없어서 되게 막막했어요. 가끔 일 하다가 막힐 때가 있는데, 모르는 것은 다른 분들에게 물어보기도 하고, 구글링하거나 다른 책을 찾아보기도 해요. 머신러닝 부분의 윤아님민진 : 타 회사에서 설계 관련 인턴을 했었어요. 마케팅 실무는 처음이라 모든 것이 새로워요. 채용공고와 면접에서 SNS 콘텐츠 기획 및 제작을 주로 맡게 될 거라고 했고, SNS나 블로그를 운영하고 있어서 자신이 있었어요. 그래도 확실히 실무는 다르더라고요. 사수분이 잘 가르쳐 주시는 덕에 잘 적응하고 있어요. 내 손으로 직접 무언가를 기획하고 컨텐츠를 제작한다는 것이 굉장히 재밌어요!SNS에 올라가는 컨텐츠를 만들고컨퍼런스 관련 컨텐츠를 제작하고 업무를 서포트 하고 있는 민진님Pt 2. 어반베이스의 첫 인상<인턴들이 뽑은 어반베이스의 좋은 점>1.윤아 : 사람들이 친절해요.민진 : 맞아, 뭐든 물어보면 되게 친절하게 알려주세요.2.민진 : 아, 그리고 유연 근무제 너무 좋아요. 아침에 지각하지 않으려 뛰지 않아도 되고, 사정이 있으면 빨리 퇴근할 수도 있고.수민 : 금요일에 2시에 퇴근하시는 분들도 많이 있어요. 짱이에요. 9시 13분, 사무실 풍경. 자율적으로 조절하는 업무 스케줄3. 수민 : 또, 식대 8000원! 선릉 맛집 점령! 이 정도면 굉장히 넉넉하지 않나요? 어반베이스 단체방에 올라오는 점심 사진들. 넉넉함 인정4.윤아 : 무제한 맥주가 있는 것, 그리고 근무시간에 먹어도 된다는 것! 민진 : 커피도 무제한이잖아요. 심지어 맥주, 커피 모두 밖에서 사먹는 것보다 맛있어요.사진 출처 : 스파크플러스Q. 반면, 당황했던 부분이나 힘들었던 점도 있나요?민진 : 저는 처음에 ‘ㅇㅇ님’ 이라고 부르는 것이 너무 어색했어요. 전에 하던 알바와 인턴, 모두 직급체계가 확실한 곳이었거든요. 근데 이젠 다 적응해서 아무렇지도 않아요.Pt. 3 채용 과정Q. 어반베이스를 어떻게 알게 됐어요? 수민 : 로켓펀치와 원티드에서 알게 됐어요. 그리고 유튜브나 관련기사들도 많이 검색해봤어요. 보도자료를 보니 어반베이스가 하고 있는 일이 미래를 널리 생각하고 있는 것 같아서 굉장히 좋은 영향을 줬어요.  윤아 : 저도 원티드에서 보고 알았어요. 블로그나 기사가 많아서 하나씩 다 살펴봤어요. 민진 : 저도요. 유튜브 계정에서 하나씩 다 살펴봤어요. 건축 AR에 관련된 영상이었는데, 굉장하더라고요. 그동안 제가 만들었던 허접한 모형들이 뇌리를 스쳐 지나가며.. 이런 신세계가 10년만 일찍 펼쳐졌다면 밤을 좀 덜 샜을 텐데.. 모형을 만드는 나도, 그걸 보는 교수님도, 서로 덜 괴롭지 않았을까.. 하는 생각이 들기도 했습니다 하하. 영상의 풀버전은 어반베이스 유튜브에 올라와 있습니다!Q. 자기소개서 및 포트폴리오 준비는 어떻게 했나요?수민 : 자기소개서는 다른 자기소개서들이랑 비슷했어요. 지원동기, 성장배경, 성격 등 기본적인 문항들로 채웠고 그동안 했던 프로젝트를 PPT에 정리해 제출했어요. 윤아 : 저도 거의 비슷해요. 민진 : 저는 자기소개서를 굉장히 짧게 적었어요. '왜 어반베이스에 지원했는지, 왜 나를 뽑아야 하는지' 딱 두 개만 적었어요. 포트폴리오는 건축 프로젝트, 공모전, 동아리 등 내가 했던 모든 활동을 정리해서 제출했어요. Q. 면접은 어땠나요?윤아 : CTO님이 이야기를 굉장히 잘 들어주시고 편한 분위기에서 면접이 진행되었어요. 면접을 진행하며 좋은 인상을 받았어요.수민 : 저는 조금 긴장했어요. CTO님께서 제 포트폴리오를 보고 질문을 하셨어요. 제 답변에 틀린 점도 있었는데 틀린 부분을 친절히 설명해 주시기도 했어요. 2차 면접도 역시 편안했고요.민진 : 저는 1차 면접을 마케팅팀 분들과 봤어요. 면접 자체가 제가 일방적으로 질문에 응답하는 것이 아닌, 서로 이야기를 주고 받는 '대화'에 가까웠어요. 그래서 저도 면접 이후로 더욱 좋은 인상을 받았어요. 두 번의 면접이 진행되면서 어반베이스가 하고 있는 사업들에 대해 더욱 자세히 알게되었는데, 진짜 꼭 붙고 싶더라고요. 붙어서 참 다행입니다. 마지막으로Q. 전공과는 조금 다른 길을 선택했는데, 후회는 없나요?수민 : 음, 그래도 어반베이스는 건축이 바탕이 되어 있으니까요. 건축산업이 좀 더 유연하게 바뀌고, 기술이 많이 도입 된다면, 지금 제가 보내는 이 시간들이 굉장히 값진 시간이 될 거예요. 프로그래밍과 건축 베이스의 지식이 굉장한 무기가 될 수 있다고 생각해요. 윤아 : 저도 후회는 없어요. 요즘 데이터 분석은 어딜가나 쓰이니까요. 전공을 살려 의료 쪽 데이터를 다룰 수도 있지 않을까요? 그런 의미에서 전공지식이 무용지물은 아니라고 생각해요. 민진 : 저도 후회 안해요. 건축을 전공했기 때문에 지금 어반베이스가 하고 있는 일을 훨씬 잘 이해할 수 있었어요. Q. 어반베이스를 들어오고 싶은 사람들에게?수민 : 어반베이스는 기술 집약적인 기업이라 생각해요. 프로그래밍의 아주 초입자라면 어렵겠지만 업무가 적성에 맞다면 즐겁게 일할 수 있을 거에요.민진 : 미래산업에 관심이 있다면  더욱 흥미롭게 다가올 것 같아요. 현재 국내에서 쉽게 접할 수 있는 사업이 아니기 때문에 굉장히 도움이 될 거라고 생각해요. 인터뷰 Behind 1어반베이스의 좋은 점에 대해 이야기하며 어반베이스 복지문화 중 하나인 ‘어반테이스트’의 얘기가 나왔습니다. 수민 : 아, 그 어반테이스트도 가신 분들 엄청 부러워요. 그 쓰리쁠 등심.. 나도 먹어보고 싶다. 윤아 : 나는 어반 테이스트 뽑히면 스시먹어야지. 수민 : 오마카세..!민진 : 아, 갑자기 배고프네. 다들 좋아하는 음식 있어요?윤아 : 아무거나 다 잘 먹어요.수민 : 저는 라멘이 먹고 싶네요.윤아 : 수민님 며칠전부터 라멘 얘기하셨어요. (웃음)민진 : 그럼 오늘 점심 때 먹으러 가요. 빨리 선릉역 라멘 맛집 찾아봐요. 선릉역 라멘집 호타루인터뷰 하다말고 맛집을 검색하더니 곧 우리의 행선지가 결정되었습니다! 점심으로 라멘을 먹고 셋이서 아주 뿌듯했다는 이야기. (ㅎㅎ) 인터뷰 Behind 2윤아 : CTO님과 면접보다가, 나중엔 자소서 잘 쓰는 법도 알려 주셨어요. 그래서 '아, 날 뽑지 않고 자소서 잘 써서 다른데 지원하라는 의미구나.' 싶었어요. 그래서 떨어질 줄 알았는데, 합격 전화가 와서 깜짝 놀랐어요. (웃음)수민 : 원래 공대생들이 글을 잘 못쓰잖아요. 모두 : 아, 완전 공감.선택한 길에 대해 후회는 없다는 인턴 3인방. 인터뷰를 하며 공통적으로 말했던 것은 ‘좋은 사람들과 멋있는 일을 할 수 있어 아주 즐겁고 재밌다!’는 것이었어요. 어반베이스도, 우리들도 더욱 발전할 수 있었으면 좋겠습니다. :) 어반베이스에 관심이 생기신 분들, 그래서 입사 지원을 하시는 분들 중 혹시 더 궁금한 점이 있다면 댓글에 남겨주세요. 담당자분에게 직접 물어봐 드릴게요.  그럼 이만 일하러 가보겠습니다 !출처: https://blog.naver.com/urbanbaseinc
조회수 41398

프론트엔드 개발자(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사에서 사이트안의 컨텐츠와 연관된 내용을 검색하더라도 상위에 랭크 안되는 경우가 많습니다.그렇게 된다면 검색사이트로 원하는 사이트를 찾아들어가는 지금으로는 많은 잠재이용자들의 유입을 막아 더 이상 서비스가 성장하지못하는 상황까지 갈 수 있습니다.---------------------------------------------------------------------------------------- 이렇게 제가 하는일에 대해 포스팅을 하다보니 제가 맡은 업무가 우리 크몽서비스에 얼마나 큰 영향을 주는지 알 수 있었는데요... 갑자기 제 어깨에 곰한마리가 앉은 것같은 느낌이 드네요ㅠㅠㅠㅠ (아~ 피로야가라~!!!) 지금까지 제가 공부한 내용들을 간략하게 포스팅해보았는데요.담번엔 배운것들을 쓰는 과정을 시간이 허락한다면 보여줄 수 있는 포스팅으로 찾아 뵙겠습니다. :)#크몽 #개발자 #개발팀 #프론트엔드 #인사이트 #팀원소개
조회수 2407

우아한 설계의 첫걸음, ES7의 decorator

하루가 멀다 하고 신기술이 쏟아지는 요즘 자바스크립트 또한 계속해서 새로운 모습으로 바뀌고 있습니다. ECMAScript 2015(이하 ES6)에 새롭게 등장한 Arrow function, Class, Generator 등이 그중 하나라 할 수 있습니다. 오늘은 ECMAScript 2016(이하 ES7)에서 새롭게 제안된 Decorator에 대해 알아보려 합니다.Decorator란?ES7 스펙 명세(링크)에는 Decorator를 아래와 같이 설명하고 있습니다.선언된 클래스와 그 프로퍼티들을 디자인 시간에 변경할 수 있는 편리한 문법위 문장만 봐서는 도대체 Decorator가 어떤 역할을 하는지 감이 오지 않습니다. 백문이 불여일견이라고 예제를 통해 Decorator를 어떻게 활용할 수 있는지 알아보겠습니다. 아래 코드는 Decorator를 이용해 설계한 클래스 코드의 일부입니다.@withSuperEngine class Car {     ...   @readOnly  manufacturer = 'ZOYI'   ... } 클래스와 클래스의 프로퍼티가 어떤 성질을 가지고 있는지 한눈에 보이시나요? Car는 슈퍼 엔진을 가지고 있고 manufacturer는 변경할 수 없는 값이라는 것을 소설을 읽는 것처럼 쉽게 이해할 수 있습니다. 이처럼 Decorator를 이용하면 코드를 우아하게 작성할 수 있습니다. 그렇다면 어떻게 Decorator를 정의하고 사용할 수 있을까요?Decorator는 최종적으로 채택된 스펙이 아니기 때문에 babel과 함께 사용해야 합니다. babel 설정은 링크에서 확인할 수 있습니다.Decorator의 선언 및 사용방법Decorator는 사실 함수입니다. 함수를 선언한 뒤 ‘@’ 키워드를 이용해 선언된 함수를 Decorator로 사용할 수 있습니다. @withSuperEngine, @readonly, @say.hello, @hello(...) 등이 사용 가능한 Decorator의 호출 형태입니다. Decorator는 클래스를 꾸밀지, 클래스의 프로퍼티를 꾸밀지에 따라 선언하는 방법이 달라집니다.클래스 프로퍼티의 Decorator먼저 클래스 프로퍼티의 Decorator를 정의하고 사용하는 방법에 대해 알아보겠습니다. 이 경우에는 프로퍼티의 descriptor를 인자로 받아 새로운 descriptor를 반환하는 형태를 가집니다. (descriptor에서 설정할 수 있는 여러 값은 링크를 확인해주세요.)그럼 이제 readonly 역할을 하는 Decorator를 작성하고 테스트를 해 보도록 하겠습니다.function readonly(target, property, descriptor) {     descriptor.writable = false   return descriptor } class Car {     @readonly   manufacturer = 'ZOYI' } const myCar = new Car()   myCar.manufacturer = ‘JOY’ // 새로운 값을 할당하려고 한다면 에러가 납니다. 또 다른 예제로 클래스의 프로퍼티를 열거할 때 열거 대상에서 제외하는 Decorator를 작성해 보겠습니다.function nonenumerable(target, property, descriptor) {     descriptor.enumerable = false   return descriptor } class Car {     @nonenumerable  acceleration = 10 manufacturer = 'ZOYI' } const myCar = new Car()   for (let key in myCar) {     console.log(key)  // manufacturer 만 출력이 된다. acceleration는 열거 대상에서 제외된다. } 단 몇 줄만으로 우리는 클래스의 프로퍼티를 읽기 전용으로 만든다던지 열거 대상에서 제외했습니다. 참 편리하지 않나요? Decorator의 활용은 여기서 끝나지 않습니다. 메모이제이션을 하는 메서드를 만들수 있고 클래스에 자동으로 바인드된 메서드로 만들 수도 있습니다.Decorator는 제안된 지 얼마 안 됐지만 많은 사람들이 활발히 연구 중입니다. github에는 지금도 계속해서 Decorator에 관련된 라이브러리들이 올라오고 있습니다. 그중 core-decorators.js는 미리 정의된 유용한 Decorator 패키지를 제공합니다.클래스의 Decorator클래스의 Decorator는 타겟 클래스의 생성자를 인자로 받습니다. 사용자는 인자로 받은 생성자를 입맛에 맞게 바꾼 뒤 반환을 해 주면 됩니다.function setAnimalSound(sound) {     return (target) => {     target.prototype.sound = sound     return target   } } @setAnimalSound('oink') class Pig {     say() {     return this.sound   } } @setAnimalSound('quack') class Duck {     say() {     return this.sound   } } const pig = new Pig()   console.log(pig.say()) // ‘oink’ 출력 const duck = new Duck()   console.log(duck.say()) // ‘quack’ 출력 위 코드처럼 오리나 돼지의 울음소리를 클래스 내부에서 정의하지 않고 클래스 Decorator를 사용해서 정의할 수 있습니다.(사실 이런 코드는 설계 관점에서 봤을 때 바람직하지 않지만 Decorator를 사용할 수 있는 여러 방법 중에 하나라고 봐주시면 감사하겠습니다.)클래스 Decorator는 클래스의 생성자를 바꾸는 것에 국한되지 않고 완전히 다른 클래스의 생성자로 바꿔치기도 할 수 있습니다. 아래 코드는 그 예제를 보여줍니다.function withBus(target) {     return class Bus {     say() {       return 'I am bus'     }   } } @withBus class Car {     say() {     return 'I am car'   } } const car = new Car()   console.log(car.say()) // ‘I am bus’ 출력 이런 구현 방식은 특정 상황에서 클래스 자체를 하이재킹 함으로써 전통적인 분기문 예외 처리가 아닌 보편적인 프로그래밍을 할 수 있게 도와줍니다.클래스 Decorator는 Cross-Cutting-Concern(전체 설계에서 빈번하게 나오는 관심사를 쉽게 모듈화 시키지 못하는 상황)이나 React에서 컴포넌트 하이재킹을 쉽게 해결해줄 수 있는 방법을 제공합니다. 이런 상황을 어떻게 효율적으로 처리하는지에 대해서는 Decorator를 소개하는 글의 취지에 맞지 않아 다음에 연재할 글에서 다룰 예정입니다.마무리이상으로 ES7에 새롭게 제안된 클래스 및 클래스 프로퍼티에 사용할 수 있는 Decorator에 대해서 알아봤습니다. Decorator는 Java, Python과 같은 언어에서 이미 존재하는 문법이기 때문에 이런 설계가 기존에 없던 새로운 방법은 아닙니다. 하지만 오랫동안 ES5에 머물던 자바스크립트가 ES6, ES7 그리고 최근에는 ES8까지 빠르게 변하고 있는 스펙 속에 다른 언어의 장점을 품는 것은 그 자체로 상당히 도전적인 변화라 생각합니다. Decorator 문법은 클래스와 그 파라미터를 꾸밀 수 있는 것에 멈추지 않고 함수의 파라미터에도 꾸밀 수 있게 드래프트 버전이 나온 상태입니다. 자바스크립트에서 Decorator를 이용한 우아한 설계가 어디까지 발전할 수 있는지, 그리고 향후 자바스크립트의 행보가 기대됩니다.#조이코퍼레이션 #개발자 #개발팀 #인사이트 #경험공유 #일지
조회수 1060

'구루급' 개발자란...

'구루'라는 단어는 이제 '수준급'을 넘어선 분들에게 부여되는 의미 있는 호칭이다. 특히, 개발자 사회에서는 비공식적으로 '구루급'이라고 불리는 개발자들이 있다. 이 정의에 대해서 누가 명확하게 옳다고 이야기할 수 있는 것은 아니다.다만, 30년 동안 소프트웨어 개발자로 살아오면서 만난 수많은 개발자들과 해외 유수의 개발자들과 만나고 소통하면서 느낀 개인적인 경험을 바탕으로 '구루급'에 대해서 정의를 해보겠다.매우 당연하게 이 정의는 전적으로 객관화된 것이 아닌, 매우 주관적인 기준이다.보통, '구루'급 개발자라고 불리는 분들을 보면, 오픈소스로 한 획을 그었거나, 그의 뜻을 따르는 후배들이 많거나, 특정 분야의 경험이 매우 풍부한 분들을 대상으로 이야기한다.다만, 이 기준에 '돈'을 많이 벌었거나, 특정 제품이나 게임, 서비스를 잘 만들었다는 식의 기준은 들어가는 것은 일부 논외로 하겠다. 이것은 전적으로 개인적인 기준이다. 이런 분들은 '구루급'개발자가 되기보다는, 산업적이거나 경제적으로 크게 성공한 기준이 더 높기 때문이며, 금전적으로 성공한 분들이 '후배'들에게 개발자로서의 영향력을 주는 것이 사실상 어렵기도 하거니와, 이미 비즈니스의 단계로 넘어간 분들이기 때문에 '구루급'개발자라고 이야기하기에는 모호하다고 개인적으로 이야기한다.그렇다면, 내가 생각하는 구루급 개발자의 최소한의 필요조건을 나열해 보자. 전적으로 개인적인 기준이니 너무 주관적이라고 비판하지 마시기를... 그 이유는 정말 주관적이기 때문이다.하나. 하나의 소프트웨어나 도메인을 10년 이상 장기간 개발 및 연구하고 있는가?둘. 자신만의 개발 문화에 대한 철학과 그 기준을 가지고 실행하고 있는가?셋. 자신이 소유하거나 만들어낸 개발 도구나 방법, 기술에 대해서 후배 개발자들에게 전파하고 있는가?넷. 후배 개발자들에게 존경받는 개발자로서의 기본적인 성품을 가지고 있는가?다섯. 후배 개발자들에게 자신의 롤을 양보하거나, 팀과 조직을 위해서 자신의 자리를 포기할 줄 아는가?여섯. 자신의 먹을거리를 위해서 비용을 싸게 부르지 않고, 후배들도 대우를 받을 수 있도록 너무 싸게 일하지 않아야 한다는 것을 실천하는가?제가 생각하는 '구루급'개발자의 조건입니다.분명, 이렇게 활동하는 '구루급'개발자들이 주변에 존재하고 있으며, 이를 위해서 개발자의 처우에 대해서 노력하기도 하고, 불합리한 경영자들과 논쟁을 벌이기도 합니다. 자신의 개인적인 이익만을 위해서 움직이지도 않는 그들이야말로 '구루급'개발자 아닐까요?그리고.대부분의 구루급개발자들은 충분한 대우와 보수를 받고 일하고 있습니다.그것이, 후배 개발자들의 처우와 미래를 위해서 매우 필요하다고 생각하고 있기 때문이죠.저는 '구루급'개발자를 그렇게 생각합니다.ps.최고의 개발자, 슈퍼개발자 등에 대한 호칭도 있을 수 있습니다. 제가 생각하는 '구루'급 개발자는 후배들에게 존경을 받고, 후배들의 처우나 개발자들의 미래에 대해서도 고민하고 실천하는 분들에 대해서 정의해 본것입니다.
조회수 959

스푼 라디오 오디오 랩 팀의 Jason을 만나보세요!

인상이 좋은 비결은.. 원래 이렇게 생겼어요 (찡긋)오디오 랩 팀의 막내, 알고 보니 세상 모든 매력을 덕지덕지 붙이고 다니는 Jason을 인터뷰해보았습니다.근데 대체 왜 이렇게 인상이 좋은 거예요? 출처: 알파카 월드 - 제이슨 닮은꼴"그냥 정말 원래 이렇게 생겼어요 하하. 웃는 상이예요. 사실 어릴 땐 눈이 좀 더 찢어지고(?) 올라가 있어서 좋은 인상이 아니었는데, 좋은 인상으로 변하더라고요..(나이 탓인가..) 웃는 게 습관이 되어버렸어요"인싸도 아싸도 아닌 '그럴싸'"인싸요? 아니에요 인싸. 그냥 저는 좀 알고 보면 반전도 많고 '모순덩어리' 일뿐이에요. 그래서 저를 표현하는 한 마디도 저는 '모순덩어리'라고 할래요. 예를 들면, 저는 해병대 출신인데 수영을 못하고요. 이성적인 것 같은데 또 되게 감성적이에요. 발라드를 되게 좋아하는데 제 노래방 18번은 '거꾸로 강을 거슬러 오르는 저 힘찬 연어들처럼'이에요. 사색하는 거 좋아하는데 또 가만히 있는 건 싫어요. 시간 아깝더라고요. (빵긋) 사내 제이슨 feat. 카이와 헤이든 듣고 싶은 당신의 스푼 라이프오디오 랩팀은 어떤 부서인가요?"오디오 랩팀은 스푼 라디오에서 오디오 방송 통신 기술을 연구하고 개발하는 부서입니다. 저희의 궁극적 목표는 세계 최고 오디오 기술 플랫폼이 되는 것이에요. 그리고 오디오 랩에서 제가 하고 있는 업무는 안드로이드 OS 클라이언트에 오디오 기술 개발하는 업무를 맡고 있어요. 오디오 랩팀에 막내이긴 한데.. 재간둥이 역할은 제가 맡고 있지 않아요 하하.. 저희 팀의 재간둥이 역할은 Ben님께서 하고 계십니다"스푼에 입사하기까지"제 입으로 말해도 되나요? 저는 수학을 좋아하진 않았는데, 잘했어요. 국어랑 사회 같은 문과계열 과목을 싫어했는데 이공계 쪽이 저와 적성에 맞더라고요. 수학 1등급 나왔는데 메가스터디 박 XX 선생님께 이 자리를 빌려 감사드립니다. 인강이 저를 만들어주셨어요.저의 원래 장래희망은 항공기 정비사였어요. 언제부터 비행기를 좋아했는지 모르겠지만 초등학교 때부터였던 것 같아요. 고3 때 진로를 정해야 하는데 항공정비과와 전자공학과와 고민을 했었어요. 그러다가 결국엔 전자 공학과 에 진학하게 되었고 자연스럽게 꿈 하고 멀어지게 되더라고요. 사실 항공 소프트웨어 쪽으로 일을 하게 될 줄 알았는데 다른 쪽으로 방향이 틀어지다 보니 어느덧 30대가 되어 있었어요. 사실 처음에 저는 스타트업에서 일하게 될 줄 몰랐어요. 이직을 준비하던 차에 제가 직접 스푼 라디오를 사용해보고, 기사도 읽게 되었고 Neil(대표)의 세바시 강연을 보고 이곳에서 일하고 싶다! 비전이 있다!라고 생각해서 오게 되었어요"내가 함께 일하고 싶은 사람서글서글한 사람을 좋아해요. 제가 그렇게 잘 못하는 편이라서요. 낯을 좀 많이 가리는데 저와는 다른 성향인 사람이라면 시너지 효과가 날 것 같아요파일럿 제이슨알고 싶은 Jason의 이야기해병대 출신부터 비행기 조종사까지"제가 안 그래 보이지만.. 사실 해병대 출신이에요. 해병대 왜 갔냐고 물어보신다면, 멋있어 보여서 가게 되었어요. 그게 전부예요. 복식 호흡하는 게 멋있어 보이더라고요. 원래 하고 싶은걸 다 하면서 살자라는 위주인지라, 꼭 무엇이든 하고 말거든요. 원래 꿈이 비행기 조종사였는데 꿈을 못 이루었으니 취미로도 해보자!라는 생각이 들어서 시작하게 되었어요. 한국에서도 할 수 있는데 제약이 너무 많아서 회사를 그만두고 미국에 갔어요. 여태 모아둔 돈 다 쓰고 왔어요. 4개월 정도 미국에서 하루 10시간씩 비행을 했었는데, 정말 행복했어요. 고등학교 때는 사실 실용음악도 준비했었어요. 아카펠라 중창단에 속해있었는데 2학년이 되고 이걸 진로로 결정하기엔 아니라고 판단이 들어서 그만두긴 했지만요. 그래서 대학교에 들어가고 밴드부에 들어가서 보컬을 맡았었어요. 저 점심시간에 혼자 코노가요. 같이 가기엔 부끄러워서.. 혼자 갑니다"유노윤호의 열정, 최강창민의 쿨함"제가 원래 자소서에 경청을 잘하는 사람이라고 적었는데 사실 가끔 듣는 것도 귀찮아요 하하.. 그리고 본인 이야기하는 것도 민폐라고 생각해서 잘하지 않는데 인터뷰하다 보니 엄청 많이 하게 되었네요. 근데 또 제가 남한테 지는 거 안 좋아해서 벤이랑 운동 누가 더 많이 하나 내기해서 요즘 매일 아침 출근 전에 수영 배우고 있고 화, 목은 영어학원을 다니면서 자기 계발을 하고 있어요. 목표가 없으면 안 되는 것 같아서 늘 목표를 일부러 세워요. 그래서 예전엔 사진도 배우러 다녔어요. 아 참! 수영을 배우다 보니 요즘 새로운 목표는 '라이프 가드'를 하고 싶어 졌어요. 이렇게 하고 싶은걸 하면서 열정적이게 살게 된 계기는 아마 아버지의 영향이 큰 것 같아요. 아버지가 매일 이렇게 말씀해주셨거든요"꿈을 꾸고 살아라, 돈은 따라온다! 반려견 '나무'의 아빠 Jason"저희 집 강아지 이름이 '나무'인데요. 식목일이 생일이라서 나무라고 지었어요. (나무 이야기할 때 눈빛이 초롱초롱해지면서 나무의 사진 보여주시던 제이슨) 나무는 귀엽고요. 비가 오나 눈이 오나 항상 저를 반겨줘요. 그래서 고마운 친구예요. 회사랑 집이 거리가 좀 멀어서 자취를 할까 생각했는데, 그러면 강아지가 혼자 집에 있어야 하니 안쓰러워서 하고 싶지 않았어요. 제가 없더라도 다른 가족들이 나무를 보살펴 줄 수 있어서 다행이라고 생각해요.팀원들이 Jason을 한마디로 표현한다면?Ian: JSON - "가볍고 빠르고 효과적이어서"*JSON [JavaScript Object Notation] :경량의 DATA교환 형식Ben: 알파카계의 알파치노 - "알파카처럼 온순한 외모의 소유자이지만 속엔 야망과 강한 카리스마를 가진 남자라서"
조회수 702

AWS IoT Core 활용하기

이 포스팅에 실린 실습은 AWS CLI가 설치되어 있고, AWS credentials이 설정되어 있는 상태에서 진행했습니다. 서버와 하드웨어 사이의 TCP 연결을 구현하지 않고 AWS IoT를 이용해 MQTT 프로토콜로 데이터를 송수신하는 환경을 구성해보겠습니다. 진행을 위해 AWS IoT와 NodeJS가 필요합니다.1.AWS IoT Core로 접속해 사물을 생성합니다. 테스트로 1개만 사용할 것이므로 “단일 AWS IoT 사물”로 등록합니다.2.‘인증서 없이 사물 생성’을 클릭합니다. 인증서는 사물 등록 후에 생성할 예정입니다.3.사물이 정상적으로 등록되었는지 확인합니다.4.루트 CA 인증서를 생성합니다. 4-1.개인키를 생성하기 전, openssl 설정 파일을 추가해 아래 내용으로 저장합니다. 아래와 같이 진행하는 이유는 basicConstraints = true로 설정하기 위해서입니다.4-2.개인키를 생성합니다.openssl genrsa -out rootCA.key 2048 4-3.루트 인증서를 생성합니다.openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.pem -config rootCA_openssl.conf -extensions v3_ca 5.인증서를 생성합니다. 5-1.AWS IoT 등록 코드를 확인합니다.aws iot —region=ap-northeast-1 get-registration-code 5-2.개인키를 생성합니다.openssl genrsa -out verificationCert.key 2048 5-3.CSR을 생성합니다. 앞서 5-1에서 확인한 등록코드를 Common Name 항목에 입력합니다.openssl req -new -key verificationCert.key -out verificationCert.csr 5-4.인증서를 생성합니다.openssl x509 -req -in verificationCert.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out verificationCert.pem -days 500 -sha256 5-5.CA 인증서와 개인 인증서 파일들을 확인합니다.5-6.AWS에 인증서를 등록합니다.aws iot register-ca-certificate —ca-certificate file://rootCA.pem —verification-cert file://verificationCert.pem —region=ap-northeast-2 5-7.AWS에 인증서를 활성화합니다.aws iot update-ca-certificate --certificate-id 인증서 등록 후 응답으로 오는 certificateId 값 --new-status ACTIVE --region=ap-northeast-2 예)aws iot update-ca-certificate —certificate-id AAAAAABDADFDF1ABADFDFDFDF### —new-status ACTIVE —region=ap-northeast-2 5-8.AWS에 인증서 자동 등록 활성화를 켭니다.6.AWS 콘솔에 접속해 CA 인증서 등록을 확인합니다.7.AWS 콘솔에서 인증서를 생성합니다.7-1.원클릭 인증서 생성을 클릭합니다.7-2.활성화를 클릭하면 완료됩니다.8.인증서와 사물을 연결합니다.9.상호 작용 탭에서 디바이스를 연결합니다.10.환경에 맞게 선택하여 다운로드합니다.11.압축을 해제해 srart.sh를 실행하고, 연결 대기합니다.12.AWS IoT 테스트 접속 후, topic 1으로 메시지를 게시합니다.13.터미널을 확인합니다.이것으로 AWS IoT 로컬 환경이 구성되었습니다. AWS IoT를 사용하면 서버와 하드웨어를 제어하는 클라이언트 간 통신을 쉽게 하도록 다양한 구성을 할 수 있습니다. 모든 포맷은 JSON 포맷으로 송수신하며, MQTT(Message Queueing Telemetry Transport) 방식이라 양방향 통신을 쉽게 처리하고 전송할 수 있을 겁니다.참고자세한 MQTT - Publish/Subscribe 모델은 여기를 클릭하세요.글장현준 팀장 | R&D 개발3팀janghj@brandi.co.kr브랜디, 오직 예쁜 옷만
조회수 1702

다양한 형태를 지원하는 리스트 UI, 잘 그리고 계신가요?

대략 1년 반 전, 5.0 롤리팝과 함께 나타난 RecyclerView. ListView 를 이용할 때 아주 기초적이고 정석적인 개념으로 사용되던 ViewHolder pattern 을 반 강제화? 하면서 동시에 성능까지 개선한 ListView 의 개량버전.앱 시장이 활성화되면서 한 가지 타입의 뷰만 반복적으로 보여주는 단순한 구성보다는 다양한 타입의 뷰를 보여주는 앱들이 많아지고 보편화 된 시점에 이것을 구현하기 위한 Adapter.getView 메소드는 혼돈.chaos 가 되었지요. 가독성을 높일만한 나름대로의 시도를 해보고 있을 때, RecyclerView 가 갑툭튀 했고 이걸 이용하면 원하는 만큼의 많은 타입의 뷰를 “가독성 좋게 만들어 볼 수 있겠다” 라는 생각이 들었습니다.그래서 RecyclerView.Adapter 를 상속 받아 다양한 타입의 뷰를 바인딩 할 수 있게 도와주는 헬퍼 클래스, MultiItemAdapter 라는 것을 만들어 보게 됐습니다. 구 회사 프로덕트에 적용해보기도 하고, 개인 프로젝트에 넣어보기도 하고, 토스랩에서 서비스하고 있는 “잔디”에 녹여내보기도 했는데 나쁘지 않은 느낌이들어 그 과정을 공유하고 많은 분들께 피드백도 받고 싶습니다. 또, 어떻게 더 잘 활용하고 계신지 여쭙고 싶습니다.RecyclerView.Adapter 의 이해를 위해 단순단순하게 만들어보자public class BasicAdapter extends RecyclerView.Adapter { private List mItems = new ArrayList<>(); @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = LayoutInflater.from(parent.getContext()) .inflate(android.R.layout.simple_list_item_1, parent, false); return new MyViewHolder(itemView); } @Override public void onBindViewHolder(MyViewHolder holder, int position) { holder.mTextView.setText(mItems.get(position)); } class MyViewHolder extends RecyclerView.ViewHolder { private TextView mTextView; public MyViewHolder(View itemView) { super(itemView); mTextView = (TextView) itemView.findViewById(android.R.id.text1); } } ... 이런 식으로 구현하면 되는군, 하지만 내가 최종적으로 원하는 건 다양한 ViewHolder 를 다뤄야 되는 건데 ViewHolder 가 많아지는 경우 inner class 는 쓰면 안되겠다! ViewHolder 들은 따로 패키지 만들어서 관리하자. 음 근데 ViewHolder 를 구성하고 난 다음 어떻게 그려지는 지에 대해 궁금하면 다시 어댑터를 찾아가야 되고, 반대로 어댑터에서 ViewHolder 내 구성요소가 어떻게 생겼는지 궁금하면 다시 ViewHolder 찾아가서 뒤져봐야되는 군. 이건 비효율 적인 것 같다. ViewHolder에 뷰를 그리는 메소드를 하나 만들자. 아 기왕이면 추상화된 클래스를 만들어 돌려돌려 쓰자. 하나 더 Generic 을 사용하자.public abstract class BaseViewHolder extends RecyclerView.ViewHolder { public BaseViewHolder(View itemView) { super(itemView); } public abstract void onBindView(ITEM item); } 뷰를 그리는데 쓰이는 객체는 Generic 을 이용하면 ViewHolder 안에서 그리는 작업 또한 해결이 가능하겠군! 이걸 이용해서 다시 만들어보자.public class MyViewHolder extends BaseViewHolder { private TextView mTextView; public MyViewHolder(View itemView) { super(itemView); mTextView = (TextView) itemView.findViewById(android.R.id.text1); } @Override public void onBindView(String item) { mTextView.setText(item); } } ... public class BaseAdapter extends RecyclerView.Adapter { private List mItems = new ArrayList<>(); @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = LayoutInflater.from(parent.getContext()) .inflate(android.R.layout.simple_list_item_1, parent, false); return new MyViewHolder(itemView); } @Override public void onBindViewHolder(MyViewHolder holder, int position) { holder.onBindView(mItems.get(position)); } public void setItems(List items) { mItems.clear(); mItems.addAll(items); } @Override public int getItemCount() { return mItems.size(); } } 음 원하는 모양새다. 근데 이제 Adapter 에선 ViewHolder 에 들어갈 layout 이 어떤 건지 관심꺼도 되겠네. 게다가 ViewHolder 에서 layout 궁금하면 다시 또 찾아와야 되는게 문제다. 좀 더 명시적인 방법으로 Factory method 로 생성자를 제한해보자. RecyclerView.ViewHolder 는 View 를 가지는 생성자가 강제되니 이렇게 바꾸자.public static MyViewHolder newInstance(ViewGroup parent) { View itemView = LayoutInflater.from(parent.getContext()) .inflate(android.R.layout.simple_list_item_1, parent, false); return new MyViewHolder(itemView); } private MyViewHolder(View itemView) { super(itemView); mTextView = (TextView) itemView.findViewById(android.R.id.text1); } 이렇게 하면 어떤 layout 을 다루고 있는지도 금방 알 수 있겠다. 이 정도만 되도 구색을 다 갖춘듯하니 이 느낌으로 다양한 타입의 뷰들을 다뤄보자.public class BasicMultiTypeAdapter extends RecyclerView.Adapter { public static final int VIEW_TYPE_A = 0; public static final int VIEW_TYPE_B = 1; private List mItems = new ArrayList<>(); @Override public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == VIEW_TYPE_A) { return AViewHolder.newInstance(parent); } else { return BViewHolder.newInstance(parent); } } @Override public void onBindViewHolder(BaseViewHolder holder, int position) { holder.onBindView(mItems.get(position)); } public void setItems(List items) { mItems.clear(); mItems.addAll(items); } @Override public int getItemCount() { return mItems.size(); } @Override public int getItemViewType(int position) { if (position % 2 == 0) { return VIEW_TYPE_A; } else { return VIEW_TYPE_B; } } } 음 깔끔하긴 하다. 근데 getItemViewType 이 스크롤 할 때마다 불릴 텐데, 분기도 많고 연산이 생겼을 때 스크롤 속도에 괜한 영향을 줄 듯? view type 을 차라리 미리 가지고 있게 만들자. 또! 가만보니 한 타입의 객체를 이용해서 다른 스타일로 뷰를 보여줄 뿐이었네. 이것도 여러가지 객체를 담을 수 있게 만들어야지.뷰를 그릴 대상이 될 객체랑 타입을 가지는 Wrapper class 를 만들어서 해결하자. 이러면 Adapter.onBindViewHolder 랑 Adapter.getItemViewType 도 해결이 되겠군.public abstract class MultiItemAdapter extends RecyclerView.Adapter { private List mRows = new ArrayList<>(); @SuppressWarnings("unchecked") @Override public void onBindViewHolder(BaseViewHolder holder, int position) { holder.onBindView(getItem(position)); } @SuppressWarnings("unchecked") public ITEM getItem(int position) { return (ITEM) mRows.get(position).getItem(); } public void setRows(List mRows) { mRows.clear(); mRows.addAll(mRows); } @Override public int getItemCount() { return mRows.size(); } @Override public int getItemViewType(int position) { return mRows.get(position).getItemViewType(); } public static class Row { private ITEM item; private int itemViewType; private Row(ITEM item, int itemViewType) { this.item = item; this.itemViewType = itemViewType; } public static Row create(T item, int itemViewType) { return new Row<>(item, itemViewType); } public ITEM getItem() { return item; } public int getItemViewType() { return itemViewType; } } } MultiItemAdapter 완성.네, 저는 이렇게 만들어서 1년 반 정도 필요한 부분(복잡해 질만한 부분)에 이 클래스를 상속받아 구현했습니다. 사용방법을 예로들어 데이터베이스나 서버로부터 긁어온 아이템들을 타입에 따라 A, B로 나눠서 보워줘야 한다면,// MutiItemAdapter 구현 public class AdvancedItemAdapter extends MultiItemAdapter { public static final int VIEW_TYPE_A = 0; public static final int VIEW_TYPE_B = 1; @Override public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == VIEW_TYPE_A) { return AViewHolder.newInstance(parent); } else { return BViewHolder.newInstance(parent); } } } // Activity 나 Fragment 등 view 요소에서 ListAdapter item setting. public void setItems(List items) { List rows = new ArrayList<>(); for (int i = 0; i < items xss=removed>이렇게 해주면 됩니다. 그런데 위 사용방법을 보면 추가적인 새로운 타입(Row)의 List 와 반복문을 돌려야 된다는 것이 단점으로 보이는데요. 그럼 이 클래스를 사용하지 않고 직접 구현한 결과를 좀 볼까요?public class NormalItemAdapter extends RecyclerView.Adapter { public static final int VIEW_TYPE_A = 0; public static final int VIEW_TYPE_B = 1; private List mItems = new ArrayList<>(); @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == VIEW_TYPE_A) { View itemView = LayoutInflater.from(parent.getContext()) .inflate(android.R.layout.simple_list_item_1, parent, false); return new AViewHolder(itemView); } else { View itemView = LayoutInflater.from(parent.getContext()) .inflate(android.R.layout.simple_list_item_1, parent, false); return new BViewHolder(itemView); } } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (holder instanceof AViewHolder) { Item item = getItem(position); ((AViewHolder) holder).getTextView().setText(item.getName()); } else { ((BViewHolder) holder).getTextView().setText("I am B."); } } private Item getItem(int position) { return mItems.get(position); } public void setItems(List items) { mItems.clear(); mItems.addAll(items); } @Override public int getItemViewType(int position) { if (getItem(position).getType().equals(Item.ITEM_TYPE_A)) { return VIEW_TYPE_A; } else { return VIEW_TYPE_B; } } @Override public int getItemCount() { return mItems.size(); } } 뭐, 나쁘진 않습니다. 이 정도 수준으로 개발이 끝나도 되고 추가적인 확장이 필요하지 않아보인다면 굳이 MultiItemAdapter 를 쓸 필요가 없습니다.중요성을 가지는 리스트 위주의 화면에서 위와 같이 개발된다면 당장 보이는 제 불만은 onCreateViewHolder, onBindViewHolder 계속해서 분기가 들어가게 되고 getItemViewType 에서는 계속 해서 List 데이터에 접근해야 한다는 것입니다. 접근 자체가 큰 문제, 큰 영향을 끼치지 않을 정도 규모의 자료구조라면 논외로 치더라도, 뷰 타입이 조금만 늘어나도 onCreateViewHolder, onBindViewHolder 의 덩치는 엄청 커질 겁니다.예를들면 맨 마지막 아이템 타입이 B 이고 현재 추가 될 아이템 타입이 A인 경우에는 다른 형태의 디바이더를 넣어야 한다던지 하는 추가적인 확장이 이루어져야 한다면 골치가 꽤 아플겁니다. 특히 저는 위 예와 비슷하게 뷰 타입에 따라 각기 다른 아래 위 마진값을 요구받을 때, ViewHolder 마다 이전 데이터를 참고하게 만들고 동적으로 Visibility 처리를 하거나 MarginLayoutParams 를 고치는 것이 비효율적으로 느껴져서 height를 주입받는 DividerViewHolder 를 하나 만들어 사용하곤 했습니다. 이렇게 하니 각각의 ViewHolder 들이 데이터들에 의존적이지 않게 코딩이 가능했었습니다. 한 가지 더 예를들어 리스트 중간 중간 광고가 보여지게 되고 이 광고 클래스는 완전히 다른 객체로부터 보여줘야 한다 라고 했을 때 MultiItemAdapter 를 이용하면 쉽게 해결이 가능합니다.정작 근 1년간 “잔디”를 만들면서는 자주 쓰진 않았는데, 작년부터 각광받기 시작한 MVP 패턴을 사용할 때 View 에서의 로직을 최소화 하려고 한다면 써먹을 수 있는 모델로 적합하지 않나 생각이 들면서 다시 사용하기 시작했습니다. Presenter 에서 Row 를 만들어 던져주면 View 는 그것을 그대로 사용하게 만들 수 있다는 생각이 들었거든요.(아직까지는 비교적 크지 않은 부분에서만 사용하게 되서 View(MainThread)에서 Row 를 만들게 코딩해 놓은 컴퍼넌트가 더 많네요 흑흑) 더 복잡한 구조를 갖는 컴퍼넌트를 만들어야 할 때는 비동기 스레드에서 Row 까지 만들어 내보내는 것도 해볼까 하는 생각도 듭니다.제 눈에만 괜찮은 구조인지, 생각지도 못한 치명적인 단점이 있진 않은지, 구조나 설계 측면에서 안 좋은 점은 있지 않은지, 논리없이 Generic 으로 “퉁” 치고 있는 코드는 아닌지, 여러가지가 많이 궁금합니다 ^^ MultiItemAdapter 를 쓴 것과 안 쓴것의 정말 심플한 비교 소스를 열어놓았습니다 MultiItemAdapter 또, 여러분들은 어떻게 구현하고 계신지요? 여러분의 관심이 필요합니다 ! :)#토스랩 #잔디 #JANDI #개발 #개발자 #인사이트 #경험공유
조회수 988

[인공지능 in IT] 맥락인식, 말하지 않아도 알아요

오전 6시 30분. 휴대전화 알람이 울리기 시작한다. 부랴부랴 샤워를 끝내고, 나갈 채비를 하고 있으니, 5분 후 집 앞 버스 정류장에 회사로 향하는 100번 시내버스가 도착한다는 메세지가 나타났다. 버스에 몸을 싣고 사무실 근처 정류장에 내려서 걸어가는 도중, 필자가 즐겨 마시는 커피를 맛있게 내린다는 동네 카페에 대한 정보를 받았다. 어느새 다가온 점심시간에는 어제 이태원에서 과음한 것을 어떻게 알았는지, 휴대폰 잠금화면에 주변 해장국집 추천이 뜬다.그저 영화 속 이야기가 아니다. 실제 사용자의 취향과 행동 등을 분석하고, 시간, 날씨, 교통 등과 같은 외부적 환경요소를 정교하게 더한 시나리오다. 각 개인에게 필요하고, 일상을 윤택하게 만들 수 있는 유의미한 정보를 제공하는 것. ‘맥락인식’ 혹은 ‘상황인지 기술’이라고 불리는 ‘Context Recognition’의 궁극적인 목표 중 하나다.맥락인식 기술은 여러 센서로부터 수집한 데이터를 통해 사용자의 상황을 인지하고, 실시간으로 맥락을 이해하는 데 초점을 맞춘다. GPS, 와이파이, RFID, 모션 센서, 소리 등 여러 시그널을 수집해 분석하며, 사용자의 일정, 문자 메시지나 행동 정보 등을 가져와 ‘사용자가 어떤 사람인지’, 그리고 ‘현재 어떤 상황인지’ 등을 추론한다. 이와 같은 맥락인식 기술을 구현하기 위해 필요한 몇 가지 주요기술은 다음과 같다.1. 상황정보 수집사용자 인터페이스 또는 센서, 센서 네트워크 등를 통해 사용자의 위치, 활동, 생활 패턴 등 다양하고 복잡한 정보를 수집하는 기술.2. 상황정보 모델링상황정보를 가공, 저장 및 공유하는 모델링 기술.3. 상황정보 융합 및 추론사용자의 상황정보를 다른 기술과 융합해 높은 수준의 추론 기능을 제공하는 기술.4. 상황정보 교환센서, 장치 및 객체와의 상호작용을 지원하기 위해 이벤트 기반의 통신 메커니즘을 제공하는 기술.5. 지능형 에이전트사용자의 단순한 의도뿐만 아니라 감정이나 감성을 고려해 전체 상황을 자율적으로 판단, 사용자에게 적합한 서비스를 제공하는 기술.기업 입장에서 생각했을 때, 맥락인식 기술은 소비자 개인에게 특화된 서비스를 제공할 수 있는 날카로운 검이다. 간단한 예로 맥락인식을 활용한 맞춤형 광고에 대해 알아보자. 소비자 A와 소비자 B는 서울에 사는 30대 남성이고 스포츠를 좋아한다. 일반적인 검색이나 구매 히스토리에 기반한 광고와 달리 맥락인식 기술을 활용하면, 이들의 라이프스타일이나 행동패턴을 바탕으로 더 깊은 디멘션까지 분석해 세분화된 광고를 제공할 수 있다. 두 소비자 모두 스포츠를 좋아한다고 가정했을 때, A는 한강 근처에서 매일 저녁 7시 정도에 조깅하는 것을 좋아할 수 있고, B는 남산에서 새벽 6시부터 등산하는 것을 좋아할 수 있다. 미묘한 차이겠지만, 분명 다른 카테고리의 소비자로 정의할 수 있는 것이다.스켈터랩스에서 진행하고 있는 맥락인식 기술 프로젝트를 예로 들어보자. 앞서 언급한 것처럼 다양한 기기로부터 측정하는 저레벨 데이터를 수집하는 것으로 맥락인식 프로세스는 시작된다. 측정 데이터는 서버에 전송되어 시간 순으로 변경 및 취합되고, 기계학습을 통해 필터링 후 수집되며, 고레벨의 맥락으로 추상화된다. 시간, GPS, 와이파이, 모션센서, 소리, 문자메시지, 일정 등 여러 데이터를 처리해 사용자의 맥락을 이해한다. 이러한 일련의 과정 역시 맥락인식 기술의 한 부분인지라 메시지 스트림 프로세서를 기반으로 확장할 수 있는 인프라를 설계, 구축했다.실시간으로 데이터를 처리할 수 있는 파이프라인이다. 처리한 데이터는 좀 더 상위 레벨의 이벤트와 행동으로 인식되어 ‘의미‘를 지니는 데이터로 표현되는데, 예를 들어 GPS 정보를 와이파이 및 시간 등과 같은 다른 데이터와 결합하고, 방문 장소와 행동반경 등을 포함해 사용자의 장소를 식별하는 방식이다. 이러한 사용자의 행동 히스토리는 패턴인식 기술을 활용해 사용자 특정 행동을 학습하고, 이를 기반으로 ‘언제 집으로 돌아갈지‘, 혹은 ‘언제 식사를 하는지’ 등 행동을 예측할 수 있다. 결국, 맥락인식을 통해 사용자의 다음 활동을 예측할 수 있는 기술을 개발, 사용자에게 필요하고 유용한 정보와 서비스를 제공하는 것이 목표다.< 맥락인식 기술을 적용한 큐 앱 화면, 출처: 스켈터랩스 한지예, 이해연 디자이너 >얼마 전, 스켈터랩스의 맥락인식 기술 프로젝트 팀은 해당 기술을 활용해 사용자들이 일상 속에서 가볍게 사용할 수 있는 서비스가 무엇일까 고민하고, ‘큐(Cue)’라는 앱을 개발했다. 큐는 사용자가 직접 명령할 필요가 없다. 큐가 먼저 사용자의 생활을 돕기 때문이다. 날씨를 예를 들면, 사용자가 날씨를 알아보기 전에 비가 올 것 같으면 우산을 챙기라 알려주고, 덥거나 미세먼지가 많을 경우 도움 되는 정보를 알려준다. 사용자에게 전달하는 정보는 카드 메시지를 통해 잠금화면으로 표시된다.큐 프로젝트의 이민학 시니어 프로덕트 매니저는 큐를 통해 사용자가 ‘내'가 누구인지 파악할 수 있을 것이라고 말한다. 예를 들어, 나는 내가 운동을 좋아하는 액티브한 라이프스타일을 살고 있는 줄 알았는데, 실제로는 집에 누워서 영화보는 것을 더 좋아하는 사람에 가깝다는 것. 개인의 삶이 매우 중요해지는 시대이지만, 정작 내가 누구인지 확인하기 어렵기 때문에 맥락인식 기술은 다양한 용도로 사용될 수 있다.< 사용자 패턴을 분석한 유형 결과 예시, 출처: 스켈터랩스 한지예, 이해연 디자이너 >이민학 매니저는 맥락인식 기술에 대해 이렇게 말한다. 그는 “누가, 언제, 어디서, 무엇을, 어떻게, 왜로 구성된 사용자의 육하원칙을 파악하고, 더 나아가 ‘Next-육하원칙’을 파악하는 것이 진정한 맥락인식 기술입니다. 앞으로 기업 특히, 마케터들은 타겟 고객을 잡는데 굉장히 유용하게 사용할 것이라고 생각합니다”라며, “소비자 입장에서는 일상, 문화, 생활 등 세분화된 영역에서 자신의 삶을 더 윤택하게 영위할 수 있습니다. 맥락인식 기술이야말로 인간에게 정말 도움될 수 있는, ‘피부에 와닿는' 인공지능 기술이 아닐까 생각합니다”라고 설명했다.이호진, 스켈터랩스 마케팅 매니저조원규 전 구글코리아 R&D총괄 사장을 주축으로 구글, 삼성, 카이스트 AI 랩 출신들로 구성된 인공지능 기술 기업 스켈터랩스에서 마케팅을 담당하고 있다#스켈터랩스 #기업문화 #인사이트 #경험공유 #조직문화 #인공지능기업 #기술기업
조회수 996

Google I/O 2018

안녕하세요, Hyper-X에서 AI Camera Picai를 개발 중인 Android 개발자, Trent 입니다. 저는 지난 5월 8일부터 5월 10일까지 JH 님, Evan 님과 함께 다녀온 Shoreline Amphitheatre 에서 열렸던 Google I/O 2018 에 대해서 전하려고 합니다. Google I/O는 Mountain View, California에서 매년 6월에 열리는 Developer Festival로서, Sundar Pichai의 Google Keynote를 시작으로 Google의 새로운 기술들과 프로덕트를 선보이는 Session들이 3일에 걸쳐 진행되었습니다. 놀라운 AI 기술의 발전이 돋보였던 올해의 행사였습니다.SessionsKeynoteSundar Pichai의 Keynote로 시작된 올해의 행사에선 AI 기술의 발전과 그 활용이 단연 돋보였습니다. Google Duplex 가 Keynote의 가장 큰 화제였는데요, Google Assistant가 직접 헤어샵이나 식당 같은 업체에 전화하여 예약을 수행해주는 기능입니다. ‘음…‘같은 소리들을 포함하며 매우 자연스럽게 종업원과 전화를 하는 모습을 보였는데요, 어려운 질문들도 척척 대답하는 모습이 놀라웠고, Google의 ML 기술에 놀라움을 금치 못했습니다.또한 Google의 독보적인 AI 기술은 Google의 기존 서비스들에도 큰 변화와 개선점들을 가져왔는데요, Gmail 의 Smart Compose 기능이 그 중 하나입니다. 이메일 작성 시 문장 전체를 AI가 autocorrect 해주는 기능인데요, 반복적인 이메일 업무를 획기적으로 줄일 수 있을 것으로 기대되었습니다. 역시 Google의 엄청난 양의 데이터를 통해 이뤄낸 기술로 보입니다. 그 외에도 Google News의 자동 뉴스 큐레이션 시스템, Google Lens를 활용한 Google Maps의 AR 기능 등으로 기존 서비스들에 큰 변화를 선도해가는 면모를 보였습니다.Android P는 Adaptive Battery, Adaptive Brightness, App Actions, App Slices 등의 새로운 AI 기반 기능들을 Android에 가져왔습니다. 배터리를 30% 절약하고, 밝기를 자동으로 조절해주며, 시간 및 행동에 따라 연관된 앱들을 추천해주는 등 전반적으로 Android가 매우 똑똑해지는 부분을 보여 줬습니다. 이런 직관적인 AI 를 활용한 API 를 활용하면, 앱 개발자가 효율적으로 자기 앱의 접근성을 높일 수 있을 것으로 보입니다.또한 Android P 는 소소한 UX 개선 점들과 더불어 스마트폰 중독 방지 기능들을 탑재했습니다. 서양에서는 과도한 스마트폰 사용이 많은 사회적 문제가 되고 있는데요, 이를 방지하기 위해 App들에서 보낸 시간을 트래킹하고, App 시간 제한을 스스로 설정한다던가, 핸드폰을 뒤집어서 중요한 연락처의 전화가 아니면 받지 않는 등의 기능을 탑재하였습니다.What’s new in AndroidAndroid App Bundle 이 소개되었습니다. 하나의 패키지를 Google Play에 업로드 함을 통해 Android 디바이스가 필요한 리소스만 다운받을 수 있게 해주는 시스템인데요, 이미 Twitter, LinkedIn 등의 어플리케이션에 적용되어 20% 가 넘는 APK 사이즈 개선을 이뤄냈다고 합니다. 저희 팀이 개발 중인 Picai에도 APK 사이즈 문제가 있는데, 이를 통해 해결 가능할 것이라 생각하고 큰 기대를 하는 중입니다. 차후 버전인 Android Studio 3.2 버전부터 지원합니다.Android Jetpack 이 소개되었습니다. Support Library, Architecture Components, KTX 등의 라이브러리를 통합한 모양새 인데요, 이와 함께 AndroidX 로의 패키지 명 변경이 이뤄지었습니다. 그 외에도 새로운 Navigation 라이브러리, WorkManager 라이브러리 등이 소개 되었습니다. Google의 새로운 Android 개발 Best Practice 제시라고 할 수 있겠습니다. Picai에서 이미 적극적으로 사용하던 기술들이라 큰 감흥은 없었는데요, Google이 직접 나서서 Android 개발자 에코시스템을 정리하려는 노력은 좋았습니다.또한 Kotlin의 전반적인 지원 확대와 다양한 라이브러리들에 대한 소식, Android Studio 의 많은 내부 변경 및 Energy Profiler, Google Assistant와 관련된 다양한 API 들 제공, Android P에 변경된 Background 카메라 및 마이크 권한 제한 및 ImageDecoder 등에 대한 뉴스 및 다양한 안드로이드 최적화에 관한 세션이 있었습니다. 특히 Android Testing 관련 세션이 매우 인상깊었는데요, 모든 Android 테스팅에 관련된 불편함을 해결해 줄걸로 기대했지만 아쉽게도 런칭이 아직 안됬는지, 컨퍼런스 밖에서는 자취를 찾을 수 없었습니다... And MoreFirebase ML Kit 및 TFLite(TensorFlow Lite) 에 대한 발표가 인상깊었습니다. 머신러닝에 대한 접근성을 높여 어떤 개발자라도 ML을 활용한 콘텐츠를 쉽게 만들게 할 수 있도록 노력하는 모습이 돋보였습니다. 컨퍼런스 후 팀원들과 함께 자세하게 검토를 해보았으며, 아직 여러가지 제약사항이 있어 적극적으로 쓰고 있진 않지만, 앞으로의 간편한 ML 활용에 대한 기대를 불러일으키는 세션들이었습니다.Google의 새로운 Cross-Platform Framework Flutter 에 대한 세션도 참가하였는데, 개발 난이도가 쉬워 보이고 좋은 애니메이션의 UI Component 들이 제공됨은 동의 함에도 기능 분리 적인 면에서 노력이 많이 필요하겠다는 생각이 들었습니다. Hyper-X의 여러 팀들에서 도입을 검토로 하고 있지만, 아직 실무에서 적용하기는 시기 상조로 보였습니다.Snapchat Camera API 에 대한 설명을 들었는데, 기기 및 유저 데이터 기반으로 두 버전의 Camera API 및 캡쳐 메커니즘을 전부 지원하는 백엔드를 세세히 설계한 부분이 매우 인상 깊었으며, 차후 Picai에 직접 적용해보고 싶다는 생각을 가지게 되었습니다. 특히 관련하여, Fragmentation이 심한 Android Camera의 Testing을 어떻게 진행하나 궁금하여 강연 후 연사에게 찾아가 여쭤보았는데요, 만족할 만한 수준의 대답은 아니었지만 향후 Picai를 개발 함에 있어 자신감을 가질 수 있게 하는 답변을 받았습니다.Office Hour개인적으로 Google I/O 참가하면서 기대했던 것은 Office Hour 인데요, Jake Wharton, Kotlin 개발팀, Flutter 팀, TFLite 팀 등을 직접 만나서 질문을 할 수 있었다는 것이 기대되었습니다. Kotlin 개발팀과 바람직한 Kotlin 코드 스타일(Effective Kotlin 유무) 및 Jetbrains가 지향하는 패러다임(FP vs OOP), Kotlin Native의 런칭 일정 및 Coroutine 후 추가 목표 피쳐 등에 대해 토의하였으며, Flutter 팀에게는 Dart 채택 이유와 Flutter가 적합한 어플리케이션 타입이 무엇이냐에 대해 물었고, TFLite 팀에게는 회사 동료의 ML에 관한 질문을 슬랙으로 전달하고 답변 받는 등 뜻깊은 시간을 보냈습니다. Google I/O TipsUber 사용법을 숙지하라Silicon Valley 답게 차를 렌트하지 않은 경우 Uber를 통해 대부분 이동하게 되는데, Shoreline Amphitheatre 근처에서는 주차가 금지되어서 특정한 Uber 존으로 이동하여 차를 잡아야 합니다. 이 위치를 인지 못하고 앱만 보면서 돌아다니게 되면 길을 잃기 쉬우니, 주의하여 미리 탑승 존을 인지하면 좋습니다. 특히 야간에는 사람이 몰려서, 주의하여야 합니다. 오히려 더 아래쪽으로 내려와서, Google Campus 내에서 잡는 게 좋을 수도 있습니다.또한 Uber 운전사한테 얻은 정보인데요, Ride-sharing을 하는 Uber 플랜을 사용하면 운전사들이 쉽게 취소한다고 하니, 조금 비싸더라도 개인으로 탑승하는 Uber 플랜을 사용하는 것이 좋다고 합니다.복장을 조심하라(?)캘리포니아는 6월에 더울때는 엄청 덥고, 추울때는 엄청 춥습니다. 특히 야외에서 오래 돌아다녀야 하기 때문에, 충분한 대비가 필수 입니다. 후디같은 옷을 입으시거나, 얇은 외투를 입는 등 충분히 준비해가면 좋습니다. 저는 행사장에서  CODE 가 젹혀진 후디를 구입해서, 매일 입고 다녔는데요, 매우 유용했습니다. 선크림 같은게 제공되긴 하지만, 그래도 제때 실내에서 휴식을 취하고 물을 많이 마시는 것이 좋습니다.마치며행사장을 돌아다니며 구글의 생태계에 푹 빠져 볼 수 있었던, 뜻깊은 경험이었습니다. 특히 그들이 곧 완성되고 릴리즈 된다고 자신하는 새로운 기능들은 상상하지 못했던 것들이라 놀라웠고, 이 시점에 직접 볼 수 있다는 것이 감사했습니다. Hyperconnect에서도 Mobile AI의 심화된 적용을 위해 많은 노력을 하고 있는데요, Azar 및 새로 시도하고 있는 Picai 같은 앱들을 통해 더 특별한 가치를 제공할 수 있도록 노력하고 있으니, 많은 기대 바랍니다!링크Android PApp BundleAndroid JetpackAndroidXML KitTFLiteFlutter#하이퍼커넥트 #개발자 #이벤트 #구글 #참여후기 #꿀팁 #인사이트 #이벤트참여 #미국 #캘리포니아

기업문화 엿볼 때, 더팀스

로그인

/