스토리 홈

인터뷰

피드

뉴스

조회수 1088

2016, 개발자의 Life.. 꿈...#1

주변 개발자들의 삶이 매우 행복을 추구하는 삶으로 변해가고 있다는 것을 느낀다. 주변의 개발자들의 모습을 몇 가지 정리해보자. 이를 '지속 개발을 위한 개발자 Life 스타일'이라고 정의하겠다.개발자#A10년 넘게 개발하던 패키지를 기반으로 필요 기능을 최소화하여 1인 개발기업에 성공하였고 제주도로 내려가서 지역에 속한 분들과 호흡하는 삶을 추구하면서도 소프트웨어 개발의 핵심을 잃지 않았다. 정말, MVP 기능에 최대한 집중하면서 필요한 시장 영역을 더 확대하지 않고, 소프트웨어를 개발하고 있는 개발자와 해당 소프트웨어를 사용하는 고객과 시장에 대해서 같이 합리적으로 지속할 수 있는 지속할 수 있는 소프트웨어 개발의 삶을 이루었다.그리고, 그러한 Life환경을 주변에 전파하면서 불과 얼마 전 또 한 명의 구 루급 개발자에게 비슷한 삶의 길을 가르쳐준다. 정말 부러운 개발자들...개발자#B복잡한 업무나 더 많은 보수를 위해서 더 좋은 회사를 찾기보다는 삶이 존재하는 근무시간을 위해서 재택근무를 찾고 있다. 비용도 최대한 낮추면서 생활을 위한 회사를 찾아다니고 있다. 아무래도, 외국계 개발회사를 선택할 것 같다.개발자#C오픈소스 진형에서 인정받는 개발자이다. 본인이 원하는 오픈소스 프로젝트를 추진하는 것을 보장받고 외국계 기업의 원격근무를 선택했다. 보수도 나쁘지 않고, 근무시간은 알아서 하는 것이지만, 원격으로 일하는 것이기 때문에 '능력'을 보여주기 위해 더 많은 시간을 소프트웨어 개발에 투자한다. 굳이, 서울 시내에 있을 필요가 없기 때문에 외각으로 집도 옮겼다.개발자#D일부러, 실리콘 벨리의 스타트업을 선택했다. 조만간 상장 예정인데 매우 큰 혜택을 받을 것 같다. 그 역시 지속 개발이 가능한 삶을 추구한다.2016년 올 초의 개발자 트렌드는 '지속 개발을 위한 Life'를 지향하는 개발자들이 늘어났다고 평가해본다.우리 모두 지속개발이 가능한 삶을 지향해 보는 것은 어떨까나...
조회수 2163

레진 기술 블로그 - IntersectionObserver를 이용한 이미지 동적 로딩 기능 개선

구글 크롬 51 버전부터 DOM 엘리먼트의 노출 여부를 비동기로 처리하는 IntersectionObserver API를 사용할 수 있게 되었습니다. 이 기능을 이용하면 이미지의 동적 로딩이나 광고 배너의 노출 측정 등을 효율적으로 사용할 수 있다고 구글 개발자 블로그에서 소개하고 있습니다. 이 글에서는 기존의 이미지 동적 로딩에 대한 문제점을 짚어보고 여러 예제를 통해 IntersectionObserver의 사용 방법을 익혀 기존 기능을 개선할 수 있도록 합니다. 사용한 예제들은 브라우저의 호환성을 고려하지 않고 구글 크롬을 기준으로 작성하였습니다.기존의 이미지 동적 로딩 구현이미지의 개수가 많거나 용량이 큰 페이지를 불러올 경우 쓸데없는 네트워크 비용이 증가하고 이미지를 불러오는 과정에서 서비스 속도에 문제가 발생할 소지가 있어서 이미지가 사용자에게 보일 때만 불러오는 동적 로딩 기능이 필요합니다. IntersectionObserver를 소개하기 전에 먼저 기존 라이브러리들이 이미지 동적 로딩을 어떤 방법으로 구현하고 있는지 간단하게 알아보도록 합니다.엘리먼트 가시성 판단이미지 동적 로딩에서 가장 중요한 코드는 해당 엘리먼트가 현재 화면 내에 보이는지 알아내는 것입니다. 이를 위해 엘리먼트의 크기와 위치 값을 돌려주는 Element.getBoundingClientRect 함수를 사용하는 경우가 많습니다. 아래는 이 함수를 사용한 간단한 구현 예제입니다.function isInViewport(element) { const viewportHeight = document.documentElement.clientHeight; const viewportWidth = document.documentElement.clientWidth; const rect = element.getBoundingClientRect(); if (!rect.width || !rect.height) { return false; } var top = rect.top >= 0 && rect.top < viewportHeight; var bottom = rect.bottom >= 0 && rect.bottom < viewportHeight; var left = rect.left >= 0 && rect.left < viewportWidth; var right = rect.right >= 0 && rect.right < viewportWidth; return (top || bottom) && (left || right); } 이벤트 처리위에서 구현한 isInViewport 함수는 언제 호출해야 할까요? 먼저 문서를 처음 불러왔을 때 호출해야 합니다. 그 후에는 동적 로딩이라는 단어에 맞게 사용자의 동작에 따라 보이지 않던 엘리먼트가 보이게 되는 이벤트를 감지해야 합니다. 마우스나 터치로 스크롤을 통해 문서의 위치가 바뀌거나 브라우저의 크기가 바뀔 수도 있고 모바일 기기의 화면을 돌려서 볼 수도 있습니다. 데스크톱의 경우 scroll, resize 이벤트를, 모바일의 경우 orientationchange 이벤트의 처리를 생각해야 합니다.const images = Array.from(document.querySelectorAll('img')); document.addEventListener('scroll', () => { images.forEach(image => { if (isInViewport(image)) { image.onload = () => images.splice(images.indexOf(image), 1); image.src = 'original_image_path'; } }); }); 간단하게 위 코드와 같이 구현할 수 있습니다. 물론 실제 서비스를 위해서는 수정할 점이 몇 가지 있습니다. 동적 로딩의 대상이 되는 이미지를 구분하기 위해 해당 엘리먼트에만 특정 클래스를 부여하거나 HTML5에서 지원하는 data 속성을 이용하기도 합니다. 스크롤이나 리사이즈 이벤트가 과도하게 발생하는 경우가 많으므로 throttle 또는 debounce 등을 사용해 실행 빈도를 조절할 수도 있습니다. 일부 라이브러리에서는 requestAnimationFrame을 이용해 이벤트 핸들러를 처리하기도 합니다.TADA레진코믹스에서는 이미지 동적 로딩을 위해 서비스 초기에 Unveil 라이브러리를 사용했었습니다. 그러나 적용 후 몇 가지 아쉬움이 있어 따로 TADA 라이브러리를 제작했습니다. 먼저 마크업 구조상 이미지를 태그가 아닌 다른 태그에 배경 이미지로 사용하는 경우를 지원해야 했습니다. 그리고 모바일 웹에 주로 많이 적용하는 수평 스크롤 구역에 대한 처리도 필요했습니다. 문서의 스크롤 이벤트로는 처리가 되지 않기 때문에 특정 엘리먼트를 받아 그 엘리먼트의 스크롤 이벤트 핸들러를 등록할 수 있도록 해야 했습니다. 이를 해결하기 위해 만든 라이브러리를 현재 서비스에 적용 중이지만 이 라이브러리 역시 아래와 같은 문제점들을 가지고 있습니다.</> < id>기존 이미지 동적 로딩의 문제점getBoundingClientRect 함수의 문제점위 코드에서 특정 엘리먼트가 현재 화면 내에 보이는지 검사할 때 사용하던 Element.getBoundingClientRect 함수에는 치명적인 단점이 있습니다. 이 함수를 호출할 때마다 브라우저는 엘리먼트의 크기와 위치값을 최신 정보로 알아오기 위해 문서의 일부 혹은 전체를 다시 그리게 되는 리플로우(reflow) 현상이 발생한다는 점입니다. 호출 횟수가 적을 경우에는 부담이 되지 않지만, 이 함수는 위에서 구현한 것처럼 스크롤이나 리사이즈 이벤트가 발생할 때마다 등록한 모든 엘리먼트를 순환하면서 호출하게 됩니다. 이 코드들이 하나의 메인 스레드에서 실행되기 때문에 스크롤을 할 때마다 실행 속도가 눈에 띄게 느려질 수도 있습니다.외부 도메인 문서를 사용하는 iframe최신 브라우저들은 동일 도메인 정책에 따라 iframe 내의 외부 도메인 문서에서 현재 문서에 접근하지 못 하게 막고 있습니다. 이 제한은 서비스 개발에서 겪게 되는 문제는 아니고 외부 광고 플랫폼 개발자의 입장에서 발생하는 문제입니다. 광고 이미지의 표시나 클릭 이벤트의 처리 등은 iframe 내에서 처리할 수 있지만 광고 이미지를 지연 로딩한다거나 이 광고가 사용자에게 노출이 되었는지 기록하는 등의 기능은 iframe 내에서 불가능합니다. 그래서 광고를 적용하는 서비스 개발자에게 스크립트를 제공하고 서비스 문서 내에 삽입하는 방식으로 처리하고 있습니다. 이러한 외부 광고가 여러 개라면 삽입해야 하는 코드가 늘어날 뿐만 아니라 코드 내에서 스크롤이나 리사이즈 이벤트 등을 각각 사용하기 때문에 위에서 언급한 문제점들이 배가될 수 있습니다.기타 이벤트에 대한 처리대부분의 동적 로딩 라이브러리들은 적용할 엘리먼트에 특정 클래스 또는 data 속성을 부여하면 코드를 추가 작성하지 않더라도 쉽게 사용할 수 있습니다. 하지만 화면에서 보이지 않던 엘리먼트가 갑자기 나타나는 현상은 스크롤이나 리사이즈 이벤트에서만 발생하는 것이 아닙니다. 더보기 버튼을 눌렀을 때 숨겨져 있던 엘리먼트를 노출할 수도 있고 AJAX 호출 후 엘리먼트를 생성한 후 보여줄 수도 있습니다. 이런 경우 일괄적으로 처리하기가 어렵우므로 해당 이벤트가 발생할 때 수동으로 처리하는 수밖에 없습니다.IntersectionObserver위에 나열한 문제들을 효과적으로 처리하기 위해 크롬 51/엣지 15/파이어폭스 55 버전부터 IntersectionObserver를 지원하기 시작합니다. 우리말로 번역하면 교차 감시자 정도가 될 이 기능은 등록한 엘리먼트가 보이는 영역에 나타나거나 사라질 때(용어에 충실하자면 대상 엘리먼트의 영역이 루트 엘리먼트 영역과 교차하기 시작하거나 끝났을 때) 비동기로 이벤트를 발생시켜 줍니다. 기본적인 사용법은 아래와 같습니다.const intersectionObserver = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) { // do something observer.unobserve(entry.target); } }); }); intersectionObserver.observe(element); 먼저 IntersectionObserver 생성자에 콜백 함수를 인자로 넘겨주고 생성한 인스턴스의 observe 메소드를 통해 동적으로 처리할 엘리먼트를 등록합니다. 콜백 함수는 IntersectionObserverEntry 객체 목록을 전달받으므로 순환문을 통해 각 엘리먼트에 대한 처리를 완료하고 필요한 경우 unobserve 메소드를 이용해 감시 대상에서 해제할 수 있습니다.IntersectionObserver 예제아래 예제들은 기본적으로 아래 코드를 바탕으로 작성되었습니다. 각 예제들의 최상단에 엘리먼트에 짝을 이룬 표시등을 두었고 콜백 함수가 호출될 때마다 파동 효과를 주었으며 이 때 isIntersecting 속성을 기준으로 표시등을 켜지거나 꺼지게 되어 있습니다.const io = new IntersectionObserver(entries => { entries.forEach(entry => { // isIntersecting 속성으로 해당 엘리먼트가 보이는 지 표시 }); }); Array.from(document.querySelectorAll('.box')).forEach(box => { io.observe(box); }); 스크롤 이벤트를 다루지 않더라도 엘리먼트의 가시성 여부를 isIntersecting 속성을 통해 알 수 있습니다.<iframe class="demo" data-fr-src="https://cdn.rawgit.com/fallroot/intersectionobserver-examples/master/basic-verticalscroll.html" width="600" height="400" frameborder="0">수평 스크롤의 경우에도 overflow 속성이 적용된 컨테이너 엘리먼트의 스크롤 이벤트를 처리하지 않더라도 상관없습니다.<iframe class="demo" src="https://cdn.rawgit.com/fallroot/intersectionobserver-examples/master/basic-horizontalscroll.html" width="600" height="200" frameborder="0">더보기 버튼에 대한 클릭 이벤트를 따로 등록하지 않아도 동작합니다.<iframe class="demo" src="https://cdn.rawgit.com/fallroot/intersectionobserver-examples/master/basic-unfold.html" width="600" height="240" frameborder="0">리사이즈 이벤트 역시 따로 처리할 필요가 없습니다. 새 창을 띄운 후 창 크기를 조절하면서 확인할 수 있습니다.위의 모든 예제들은 <iframe> 태그 안에서 실행되고 있습니다. 이처럼 작성한 코드가 외부에서 실행이 되더라도 IntersectionObserver API는 문제없이 동작합니다.IntersectionObserver 생성자 옵션rootroot 옵션에는 가시성의 판단 기준이 될 HTML 엘리먼트를 지정합니다. observe 메소드로 등록하는 엘리먼트들은 반드시 이 루트 엘리먼트의 자식이어야 합니다. 이 옵션을 지정하지 않을 경우 브라우저 화면에서 현재 보이는 영역인 뷰포트가 기본이 됩니다. 아래 예제에서 알 수 있듯이 루트 엘리먼트를 지정하면 현재 화면과는 상관없이 루트 엘리먼트와 등록한 엘리먼트들의 영역이 교차하는 지 판단하게 됩니다.<iframe class="demo" src="https://cdn.rawgit.com/fallroot/intersectionobserver-examples/master/option-root.html" width="600" height="400" frameborder="0">rootMargin루트 엘리먼트의 마진값을 지정할 수 있습니다. CSS에서 사용하는 형식과 같기 때문에 “10px”, “10px 20px”, “10px 20px 30px 40px” 형태가 모두 가능하며 음수값으로 지정할 수도 있습니다. 기본값은 0이고 루트 엘리먼트를 지정한 상태라면 퍼센트값을 사용할 수도 있습니다. 이 옵션을 이용하면 이미지 동적 로딩에서 해당 엘리먼트가 화면에 나타나기 전에 이미지를 불러오기 시작해 이미지 공백을 줄이는데 유용하게 이용할 수 있겠습니다.<iframe class="demo" src="https://cdn.rawgit.com/fallroot/intersectionobserver-examples/master/option-rootmargin.html" width="600" height="400" frameborder="0">위 예제에서는 root 옵션은 지정하지 않고 rootMargin 옵션을 각각 0, 100px, -100px, 50%로 지정했습니다. 하지만 iframe 내에서 실행을 하게 되면 이 옵션이 정상적으로 동작하지 않습니다. 프로젝트 페이지의 이슈 댓글에는 동일 도메인의 프레임 안에서는 동작하는 것으로 논의되고 있지만 뷰포트에는 해당하지 않거나 버그 또는 아직 크롬에 반영이 되지 않아 보입니다.이 예제는 새 창을 띄워 프레임을 벗어나면 정상적으로 동작합니다. 스크롤을 내리다보면 엘리먼트마다 IntersectionObserver 콜백 함수가 다른 위치에서 호출됨을 알 수 있습니다.thresholdthreshold 옵션은 엘리먼트가 콜백 함수의 호출 시점을 정하는 옵션입니다. 0과 1을 포함한 그 사이의 숫자 또는 숫자 배열을 지정할 수 있는데 이 숫자는 엘리먼트의 전체 영역 중에 현재 보이는 영역의 비율입니다. 이 비율의 경계를 넘나들 때마다 콜백 함수가 호출됩니다.<iframe class="demo" src="https://cdn.rawgit.com/fallroot/intersectionobserver-examples/master/option-threshold-value.html" width="600" height="400" frameborder="0">위 예제에서는 threshold 옵션을 각각 0, 0.5, 1, [0, 1]로 지정했습니다. rootMargin 예제처럼 엘리먼트마다 콜백 함수가 다른 위치에서 호출됩니다. 두 번째와 세 번째 상자는 콜백 호출 시점에 isIntersecting 값이 항상 참이기 때문에 표시등이 정상적으로 표시되지 않습니다. isIntersecting 속성을 기준으로 처리해야 할 작업이 있다면 반드시 threshold 속성에 0을 포함시켜야 정상적으로 동작합니다. threshold 속성은 아래 예제처럼 콜백 함수의 인자로 받는 IntersectionObserverEntry 객체의 intersectionRatio 속성과 같이 사용하기에 유용합니다.<iframe class="demo" src="https://cdn.rawgit.com/fallroot/intersectionobserver-examples/master/option-threshold-ratio.html" width="600" height="400" frameborder="0">위 예제에서는 threshold 옵션을 각각 [0, 1], [0, 0.5, 1], [0, 0.25, 0.5, 0.75, 1]로 지정하고 콜백이 호출되면 intersectionRatio 값을 기준으로 표시등의 배경 투명도를 바꾸도록 했습니다.IntersectionObserver의 활용이미지 동적 로딩지금껏 알아본 IntersectionObserver를 이용해 이미지 동적 로딩을 간단하게 구현해봅니다. 이미지 엘리먼트를 구성할 데이터가 배열로 존재한다고 가정하고 ES6에서 지원하는 템플릿 문자열을 사용해 배열을 순환하면서 이미지 목록을 생성합니다. 그 후 IntersectionObserver를 초기화하고 만들어진 엘리먼트들을 등록합니다. 콜백 함수에서는 엘리먼트가 보이는 상태일 때 이미지를 로딩하고 해당 엘리먼트를 감시 해제합니다. id="comics"> const comics = [ { alias: 'eunsoo', id: 6080299074584576, title: '은수' }, ... ]; const template = comics => ` ${comics.map(comic => ` ${comic.id}"> ${comic.alias}" class="info">${comic.title} `).join('')} `; document.getElementById('comics').innerHTML = template(comics); const io = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { if (!entry.isIntersecting) { return; } const target = entry.target; const id = target.dataset.id; target.querySelector('.info').style.backgroundImage = `url(https://cdn.lezhin.com/v2/comics/${id}/images/wide?width=600)`; observer.unobserve(target); }); }); Array.from(document.querySelectorAll('.comic')).forEach(el => { io.observe(el); }); 아래 예제를 실행하면서 브라우저의 개발자 도구를 열고 네트워크 탭을 살펴보면 이미지 엘리먼트가 보이기 시작할 때 불러오기 시작하는 것을 확인할 수 있습니다.<iframe class="demo" src="https://cdn.rawgit.com/fallroot/intersectionobserver-examples/master/demo-lazyload.html" width="600" height="400" frameborder="0">무한 스크롤IntersectionObserver 기능을 이용하면 무한 스크롤 역시 쉽게 구현할 수 있습니다. 아래 예제에서는 스크롤의 끝부분에 감시를 할 엘리먼트를 두고 그 엘리먼트가 노출이 될 때마다 콘텐츠를 추가로 불러오도록 작성하였습니다. id="items"> id="sentinel"> const count = 20; let index = 0; function loadItems() { const fragment = document.createDocumentFragment(); for (let i = index + 1; i <= index + count; ++i) { const item = document.createElement('p'); item.classList.add('item'); item.textContent = `#${i}`; fragment.appendChild(item); } document.getElementById('items').appendChild(fragment); index += count; } const io = new IntersectionObserver(entries => { entries.forEach(entry => { if (!entry.isIntersecting) { return; } loadItems(); }); }); io.observe(document.getElementById('sentinel')); loadItems(); 실행 결과를 아래 예제에서 확인할 수 있습니다.<iframe class="demo" src="https://cdn.rawgit.com/fallroot/intersectionobserver-examples/master/demo-infinitescroll.html" width="600" height="400" frameborder="0">마무리IntersectionObserver API는 아직 몇몇 브라우저의 최신 버전에서만 사용할 수 있지만 지원하지 않는 브라우저를 위해 Polyfill을 제공하고 있습니다.IntersectionObserver API는 웹 광고 플랫폼 제공자와 사용자 모두에게도 좋은 소식이라 봅니다. 이 API가 정착된다면 광고 노출 여부를 측정하기가 쉬워지고 서비스에 더해졌던 리소스 낭비를 줄일 수 있을 것이라 생각합니다.레진코믹스는 크롬 브라우저 사용자의 비중이 높은 편이기 때문에 빠른 시일 안에 적용해 볼 예정입니다. 이미지 동적 로딩 기능의 개선과 정주행 기능과 같이 현재 스크롤 이벤트를 과하게 사용하고 있는 코드에 대한 부담을 덜 수 있기를 기대하고 있습니다.참고자료Intersection Observer API SpecificationIntersectionObserver’s Coming into ViewIntersection Observer API
조회수 1358

레진 기술 블로그 - Kotlin의 빛과 그림자

핀터레스트의 안드로이드 개발팀이 코틀린을 도입하면서 겪은 어려움과 해결책을 소개한 The Case Against Kotlin을 foot번역하고 자의적으로 해석하고 요약했습니다. 저자 라이언 쿡(Ryan Cooke)은 현재 코틀린이 가트너의 하이프 사이클에서 “뻥튀기된 기대감의 산(Peak of Inflated Expectations)” 쯤에 있다고 말합니다. 레진시 개발동에서는 이미 코틀린을 부분적으로 도입했고, 현재는 범위를 넓혀가는 중인데요… 정말 괜찮은 걸까요?문제: 학습 곡선자바 개발자로서 문법에 익숙해지는 데 1주일 정도 걸립니다.코틀린을 이미 잘하는 사람이 없으면 베스트 프랙티스들을 찾아보면서 해야하는 데 시간이 듭니다.코틀린 사용을 가속화 시키는 데 팀 트레이닝을 계속 해야합니다. -> 기회비용 많이 듭니다.하기 싫어 하는 사람도 있고…혼자서 알아서 잘 배우는 사람도 있고…해결책: 학습 곡선코틀린은 아직 말년병장성숙한 언어가 아닙니다! 지금도 자라나고 있습니다! 그게 제일 무서워..책도 있고 인터넷 리소스도 있지만, 코틀린 신봉자가 하나 있어서 다 가르쳐주는 게 짱입니다.필자가 코틀린을 하고 싶었던 이유는 생산성인데요, 동료들 중에는 그렇게 느꼈던 사람들이 많지 않은 것 같습니다. 정착이 되면 보이겠죠.문제: 빌드 속도Gradle 빌드 속도는 보통 30초, 클린 빌드는 75초 까지 걸립니다.코틀린은 보통 빌드 속도의 25%, 클린 빌드의 40% 밖에 안나옵니다.해결책: 빌드 속도알아서 하셈 ㅋ코틀린 파일 하나 변환 -> 클린 빌드 시 조금 시간이 더 걸립니다. 파일을 많이 변환할수록 느려지긴 하지만 체감하긴 어렵습니다.보통 빌드할 때는 코틀린 파일 많아도 상관 없습니다.결론: 클린 빌드할 때 느려진다는 걸 체감할 겁니다.문제: 개발 안정성코틀린의 문법이나 특성이 문제가 아니라, 코드를 생산성 있게 작성하는 자신을 막는 새로운 문제들 때문이라고 생각합니다.사실 그냥 코틀린 배우기 싫은 거 같아요.예를 들면, 코틀린 애노테이션 프로세서 툴(kapt) 때문에 빌드가 안 되고, 무조건 클린 빌드로만 개발을 했던 적이 있습니다.이거… 코틀린 때문 아니야?!?!?! 하는 의심들 많았죠.고치느라 시간이 많이 흘렀습니다.또 어떤 문제가 튀어나올지에 대한 두려움이 커지네요.해결책: 개발 안정성그냥 IDE 나 언어의 stable 버전만 업데이트 하세요.안정된 버전들만 사용하면 그나마 힘든 일 없을거예요.정말?문제: 정적 분석FindBugs, PMD, Error Prone, Checkstyles and LintJava 는 이와 같은 툴들로 인해 Code Review에 쓸데없는 걸 줄이거나 룰을 적용할 수 있는데,코틀린에는… 이런 게 없… 분석을 위한 게 아직… 없습니다… 사람들이 알아서 다 찾아야 합니다.해결책: 정적 분석그냥 손가락빨고 기다려야 합니다. 아니면, 직접 만드세요!문제: 나 돌아갈래~돌아가기 쉽지 않습니다. 자바를 코틀린으로 옮기기에는 쉬운데, 반대는… 어렵습니다!코드가 깨지고, 변수명부터, 이런 저런 부분들을 다시 구현해야합니다.코틀린스럽거나, 코틀린의 고유한 기능들을 사용했다면, 여기서부터 헬이죠.해결책: 나 돌아갈래~되돌아오는 건 쉽지 않기 때문에 잘 생각해야 합니다.유닛 테스트가 정말 잘 된 파일들부터 바꾸세요.간단하고 재사용 가능한 잘 모듈화된 파일들을 먼저 바꾸세요.결론이 글은 고려해야 할 리스크에 대해서 나열했습니다.단점들은 구글과 젯브레인과 스택오버플로우가 차차 해결해 줄 겁니다.TL;DR 코틀린으로 작성하는 건 쉽지만, 되돌리기는 어렵습니다.그래서 말인데… 레진코믹스에서 코틀린 삽질을 함께 할 개발자를 모십니다!
조회수 2309

JPassKit 적용중 오류 발생

서비스에서 ios wallet을 제공하려고 하니, 예전과는 다르게 서버단 통신을 통해 인증받는 절차가 추가로 생겼단다. 다만, 애플에서 제공하는 서버쪽 데모를 보면 ruby로 만들어져있다. 왜 하필 루비인가? swift도 아니고… 여튼 그걸 java로 porting하려니 이미 만들어 놓은 것이 있을 것 같아서 구글링했더니, jpasskit이 그나마 제일 fork도 많이 되고, 사용도 하는 것 같아서 lib dependency를 추가했다.<!-- PassKit --> de.brendamour jpasskit 0.0.8 개발을 완료했는데, Test Case에서 오류가 나타나기 시작했다.com.fasterxml.jackson.databind.JsonMappingException: Can not resolve PropertyFilter with id 'validateFilter'; no FilterProvider configured난 jackson filter를 바꾼 적이 없는데 왜 에러가 나는 것인가? 처음에는 jpasskit issue를 보고 jackson lib의 version 호환성 문제가 있는 것 같아서 아래처럼 dependency처리를 했다.<!-- PassKit --> de.brendamour jpasskit 0.0.8 com.fasterxml.jackson.core jackson-core 위의 오류가 해결된 것처럼 보여서 SNAPSHOT version을 만들었는데, 됐다안됐다한다. 예를 들어서 local profile에서 하면 되고, develop profile에서 하면 오류나고… 혹은 전체 junit을 모두 돌리면 에러가 발생하는데, 에러나는 class만 테스트 돌리면 성공하고 ㅠ.ㅠ그래서 해당 소스를 파보다가 문제점을 발견하였다.우리의 프로젝트에서는 pojo type인 jackson object mapper를 bean으로 등록해서 사용하고 있다. bean으로 등록하면 몇 가지 장점이 있는데, 자세한 설명은 이 글의 범위를 벗어나기 때문에 생략한다.@Primary @Bean public ObjectMapper objectMapper() { ObjectMapper objectMapper = new CustomObjectMapper(); initializeObjectMapper(objectMapper); return objectMapper; }그래서 Object Mapper는 singleton으로 재사용하고 있는데, jpasskit은 Object Mapper를 변조시키고 있다.public final class PKFileBasedSigningUtil extends PKAbstractSIgningUtil { private static final String FILE_SEPARATOR_UNIX = "/"; private static final String MANIFEST_JSON_FILE_NAME = "manifest.json"; private static final String PASS_JSON_FILE_NAME = "pass.json"; private ObjectWriter objectWriter; @Inject public PKFileBasedSigningUtil(ObjectMapper objectMapper) { this.addBCProvider(); this.objectWriter = this.configureObjectMapper(objectMapper); } ...protected ObjectWriter configureObjectMapper(ObjectMapper jsonObjectMapper) { jsonObjectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); jsonObjectMapper.setDateFormat(new ISO8601DateFormat()); SimpleFilterProvider filters = new SimpleFilterProvider(); filters.addFilter("validateFilter", SimpleBeanPropertyFilter.serializeAllExcept(new String[]{"valid", "validationErrors"})); filters.addFilter("pkPassFilter", SimpleBeanPropertyFilter.serializeAllExcept(new String[]{"valid", "validationErrors", "foregroundColorAsObject", "backgroundColorAsObject", "labelColorAsObject", "passThatWasSet"})); filters.addFilter("barcodeFilter", SimpleBeanPropertyFilter.serializeAllExcept(new String[]{"valid", "validationErrors", "messageEncodingAsString"})); filters.addFilter("charsetFilter", SimpleBeanPropertyFilter.filterOutAllExcept(new String[]{"name"})); jsonObjectMapper.setSerializationInclusion(Include.NON_NULL); jsonObjectMapper.addMixIn(Object.class, PKAbstractSIgningUtil.ValidateFilterMixIn.class); jsonObjectMapper.addMixIn(PKPass.class, PKAbstractSIgningUtil.PkPassFilterMixIn.class); jsonObjectMapper.addMixIn(PKBarcode.class, PKAbstractSIgningUtil.BarcodeFilterMixIn.class); jsonObjectMapper.addMixIn(Charset.class, PKAbstractSIgningUtil.CharsetFilterMixIn.class); return jsonObjectMapper.writer(filters); }확실해졌다. 위에서 상황마다 오류가 간헐적으로 발생하는 이유는 이와 같은 것이었다. jpasskit이 실행되기 전까지는 정상적으로 동작한다. 그러다가 jpasskit을 한 번 거치면 이미 등록되어 있는 object mapper bean의 설정이 바뀌게 된다. 즉, 우리가 설정한 custom configuration들이 무시되어버려서, 전혀 엉뚱한 곳에서 에러를 일으킨다.jpasskit에서 사용하는 object mapper는 특별한 설정이 필요한 것은 아니라, bean을 사용하지 않고 기본 object mapper를 생성해서 넘기는 식으로 수정하였다.private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); ... private byte[] createPKPassBinaries(PKPass pass, PKSigningInformation pkSigningInformation, InputStream thumbnail, InputStream thumbnail2x) throws Exception { return new PKFileBasedSigningUtil(OBJECT_MAPPER).createSignedAndZippedPkPassArchive(pass, createPKPassTemplate(thumbnail, thumbnail2x), pkSigningInformation); }All Clear.해당 내용은 jpasskit에 issue reporting하여 신규 release(0.0.9)가 예정중이다.#데일리 #데일리호텔 #기술스택 #스택도입 #후기 #일지 #JPasskit
조회수 1614

스마트 컨트랙트 개발과정에서의 실수 — TransferFrom

Hexlant는 Blockchain 전문 개발 팀으로, 다양한 기관들의 스마트 컨트랙트 코드를 검수하는 업무도 진행하고 있습니다.지금까지 다양한 컨트랙트 코드들을 리뷰하면서 나왔던 문제점들을 공유하고, 더 나은 방법으로 개발 할 수 있는 방법들에 대해 이야기 해보고자 합니다.transferFrom에 대한 이해ERC-20 표준에 보면, transferFrom 이라는 함수가 있습니다. 일반적으로 많이 쓰이는 기능이 아니다 보니 잘 모르고 넘어가는 경우가 많습니다.function transferFrom(address _from, address _to, uint256 _value) public returns(bool)transferFrom은 남이 가지고 있는 토큰을 누군가에게 보내는 기능입니다.그 누군가는 내가 될 수도 있습니다.이 설명만 보면, 아래와 같은 의문이 생기실 겁니다.어? 남의 토큰을 내 마음대로 옮길 수 있다고??당연히 마음대로 옮기면 안되겠죠.그래서 approve 함수를 통해, 내 토큰을 사용할 수 있는 사람을 지정할 수 있습니다function approve(address spender, uint256 _value) public returns(bool)토큰의 holder는 approve함수를 호출하여 spender에게 일정량 만큼을 사용할 수 있게 허용을 해 줍니다. 그럼 spender는 허용된 범위 안에서 토큰을 마음대로 옮길 수 있습니다.허가되지 않은 토큰의 이동많이 쓰지 않는 기능이다 보니, 이 부분에 대해 고려하지 않고 개발 하는 경우가 있을 수 있습니다.아래는 저희가 리뷰했던 코드 중 일부입니다function approve(address _spender, uint256 _value) public returns (bool success) { require(_spender > address(0)); allowed[msg.sender][_spender] = _value; Approval(msg.sender, _spender, _value); return true; }function transferFrom(address _from, address _to, uint256 _value) public { require(_from > address(0)); require(_to > address(0)); require(balances[_from] >= _value); require(balances[_to] + _value > balances[_to]); balances[_from] = balances[_from].sub(_value); balances[_to] = balances[_to].add(_value); Transfer(_from, _to, _value); }approve 함수를 우선적으로 보면, allowed 테이블에, msg.sender가 _spender에게 얼마만큼 토큰사용을 허용해 주었는지 저장하는것 말고는 특별한 기능은 없습니다.allowed[msg.sender][_spender] = _value;이제 transferFrom 함수를 확인해 보겠습니다.transferFrom은 실제 토큰이 전송되는 부분이니 예가 필요할 것같습니다.Alice에게 10000개의 토큰이 있을 때, Bob이 transferFrom을 다음과 같이 호출했다고 합시다.transferFrom(Alice, Bob, 10000)자 이제 transferFrom코드를 따라가며 토큰이 어떻게 전송이 되는지 확인해 봅시다.require는 안에 들어간 조건이 만족해야만 다음 라인을 실행 할 수 있다는 명령어 입니다. require를 만족하지 못하면, 해당 트랙잭션은 수행되지 않고 실패로 처리됩니다.require(_from > address(0)); require(_to > address(0));위의 두 줄의 조건은 입력된 주소_from, _to는 각각 Alice와 Bob의 지갑 주소이기 때문에 0x*****형태로 0x0000…0000이 아니기에 해당 조건들을 모두 만족합니다.require(balances[_from] >= _value); require(balances[_to] + _value > balances[_to]);Alice의 지갑에는 10000개의 토큰이 있고 _value는 10000개이니까 저 require를 실제 숫자로 대입하면require(10000 >= 100000); require(0+10000 > 0);조건을 충분히 만족합니다.그 다음부분들을 실제로 Alice의 주소에서 Bob의주소로 10000개의 토큰을 옮기는 작업입니다.balances[_from] = balances[_from].sub(_value); balances[_to] = balances[_to].add(_value); Transfer(_from, _to, _value);Alice의 잔액에서 10000개만큼이 빠지고,Bob의 잔액에 10000개가 추가됩니다.balances[Alice] = balances[Alice].sub(10000); balances[Bob] = balances[Bob].add(10000); Transfer(Alice, Bob, 10000);이로서 Bob은 Alice의 토큰 10000개를 자신의 지갑으로 이동시켰습니다.일련의 과정을 요약하면1. 주소 오류 검증 2. 보내려는 토큰이 Alice가 가진 잔액보다 작은지 검증 3. 받았을때 Overflow가 발생하는지 체크 4. Alice의 잔액에서 보내는 만큼의 토큰 수량을 뺀다 5. Bob의 잔액에 보내는 만큼의 토큰 수량을 더한다과정을 보면 Bob이 Alice로 부터 토큰 사용을 허락받았는지 체크하는 부분이 없습니다.따라서 누군가가 보유한 토큰을 다른 사람이 제멋대로 쓸수 있게됩니다.오류수정transferFrom이 정상적으로 동작하려면 어떻게 수정되어야 할까요?function transferFrom(address _from, address _to, uint256 _value) public { require(_from > address(0)); require(_to > address(0)); require(balances[_from] >= _value); require(balances[_to] + _value > balances[_to]); require(allowed[_from][msg.sender] >= _value); balances[_from] = balances[_from].sub(_value); balances[_to] = balances[_to].add(_value); allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value) Transfer(_from, _to, _value); }첫 번째로는 당연히 transferFrom을 호출한 사람이 권한이 있는지 확인해야 합니다.require(allowed[_from][msg.sender] >= _value);이 조건을 통해 허용된 수량안에서만 토큰을 옮길 수 있게 만들 수 있습니다.두번째는, 토큰을 옮긴 후 허용량을 줄여주어야 합니다.allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value)만일 Alice가 Bob에게 10000개의 토큰을 허용해 주고, Bob이 그중 100개를 사용했다면, 그 다음번에 Bob은 9900개 안에서만 사용할 수 있어야 합니다.#헥슬란트 #HEXLANT #블록체인 #개발자 #개발팀 #기술기업 #기술중심 #실수담
조회수 1074

안드로이드 색상 투명도

제 깃헙블로그 https://heelog.github.io/about/ 에서 동시에 포스팅을 진행하고 있습니다.개발 관련 글을 보기에는 블로그를 통하시는 것이 더 좋습니다!안드로이드에서 색상을 표현할 때는 #AARRGGBB 형태로 표현한다. 앞의 AA 자리에 16진수를 이용하여 투명도를 표현해줄 수 있다. 범위는 0~255이다.0%~100% 투명도 값  100% — FF99% — FC98% — FA97% — F796% — F595% — F294% — F093% — ED92% — EB91% — E890% — E689% — E388% — E087% — DE86% — DB85% — D984% — D683% — D482% — D181% — CF80% — CC79% — C978% — C777% — C476% — C275% — BF74% — BD73% — BA72% — B871% — B570% — B369% — B068% — AD67% — AB66% — A865% — A664% — A363% — A162% — 9E61% — 9C60% — 9959% — 9657% — 9456% — 9156% — 8F55% — 8C54% — 8A53% — 8752% — 8551% — 8250% — 8049% — 7D48% — 7A47% — 7846% — 7545% — 7344% — 7043% — 6E42% — 6B41% — 6940% — 6639% — 6338% — 6137% — 5E36% — 5C35% — 5934% — 5733% — 5432% — 5231% — 4F30% — 4D28% — 4A28% — 4727% — 4526% — 4225% — 4024% — 3D23% — 3B22% — 3821% — 3620% — 3319% — 3018% — 2E17% — 2B16% — 2915% — 2614% — 2413% — 2112% — 1F11% — 1C10% — 1A9% — 178% — 147% — 126% — 0F5% — 0D4% — 0A3% — 082% — 051% — 030% — 00참고한 블로그: 커피한잔의 여유와 코딩#트레바리 #개발자 #안드로이드 #앱개발 #인사이트 #경험공유 #꿀팁
조회수 1373

스켈티인터뷰 / 스켈터랩스의 금손 이주현 님을 만나보세요:)

Editor. 스켈터랩스에서는 배경이 모두 다른 다양한 멤버들이 함께 모여 최고의 머신 인텔리전스 개발을 향해 힘껏 나아가고 있습니다. 스켈터랩스의 식구들, Skeltie를 소개하는 시간을 통해 우리의 일상과 혁신을 만들어가는 과정을 들어보세요! 스켈터랩스의 하드웨어팀 금손 이주현 님을 만나보세요:)사진1. 스켈터랩스의 하드웨어 엔지니어 이주현 님Q. 자기소개를 부탁한다.A. 스켈터랩스의 하드웨어 엔지니어로 일하고있는 이주현이다.Q. 스켈터랩스에서 구체적으로 어떤 일을 맡고 있는가.A. 현재는 스켈터랩스의 레고(L.ego)팀에서 곧 출시 예정인 스마트 미러, 샘(Samm)을 만들고 있다. 레고 팀은 스켈터랩스가 가진 원천 기술을 소비자가 쉽고 편하게 접할 수 있도록 디바이스(Device) 형태로 구현하는 팀이다. 우리의 원천 기술이 다양하다 보니, 이 기술을 어떻게 활용하여 어떤 제품을 만들어야 할지부터 고민한다.Q. 매번 새로운 기획을 하고 아이디어를 내는 것이 쉬운 일은 아닐 것 같다.A. 그래서 다양한 소스를 참고하고 많은 사람에게 의견을 구하려고 한다. 킥스타터(Kickstarter)나 와디즈(Wadiz)와 같은 크라우드펀딩 플랫폼을 들여다보거나 DIY 상품을 여러가지 찾아보며 영감을 얻는다. 최근에는 레고팀 PM(Product Manger)이신 아영님의 소개로 산업디자인과 수업을 청강했다. 산업디자인이 내가 일하는 분야와 아주 밀접한 것은 아니지만 학생들이 아이디어를 개진하여 그것을 발전시켜나가는 것을 보며 나 또한 아이디어를 얻을 수 있었다. 이런 과정을 통해 제품이 구체화되면 성공 가능성에 연연하지 않고 일단 개발을 시도하려 한다.Q. 실제로 제작하는 과정에서도 예기치 못한 문제에 많이 부딪히지 않나.A. 맞다. 참신해보였던 아이디어도 기능을 구체화하는 단계에 접어들면 자잘한 이슈가 생기기 마련이다. 사람마다 생각이 다르기 때문에, 고객에게 제품의 어떤 기능이 유용할 지 예상하기도 쉽지 않다. 때문에 소프트웨어 엔지니어와 디자이너, 마케터와 같은 다른 포지션의 동료들과 자주 미팅을 갖는다.제품의 구체화가 성공적으로 완료되더라도, 실제 구현이 녹록치 않다. 가령 곧 출시를 앞두고 있는 스마트 미러 제품, 샘(Samm)의 경우 사용자의 제스처(Gesture)를 인식하여 작동하는데 생각보다 카메라의 한계가 있더라. 그래서 요즘은 카메라 뿐만 아니라 다양한 센서를 활용하는 방법을 찾고있다.Q. 내가 상상했던 ‘일반적인 하드웨어 엔지니어'의 업무와는 조금 달라보인다. 기획자 역할까지 겸비하는 것으로 보이는데, 맞나.A. ‘일반적인 하드웨어 엔지니어'의 역할을 무엇이라고 정의하는지에 따라 다른 것 같다. 나는 오히려 스켈터랩스에서 하는 업무가 내가 생상했던 ‘하드웨어 엔지니어'의 업무다. 보통 엔지니어들은 직접 만들어보는 것을 좋아한다. 그렇지만 만들고 싶은 디바이스가 늘 회사의 방향성과 일치하는 것은 아니기 때문에, 집에서 홀로 개발하기에는 시간과 돈이 늘 부족하다는 하소연을 많이 듣곤 한다. 또한 회사의 규모가 커질수록 하드웨어 엔지니어는 하나의 제품을 깊게 들여다보기 때문에 전문가로 성장하는 반면, 내가 하고싶은 개발을 할 수 있는 기회는 줄어들기 마련이다. 하지만 스켈터랩스에서는 내가 상상한 디바이스를 구현하기 위해 각종 부품을 조립하여 테스트하고, 응용하여 새로운 디바이스를 만들고 있다. 그래서인지 이곳이 내게는 딱딱한 회사의 느낌이 아니다. 정확히 내가 꿈꾸고 하고싶었던 일을 할 수 있게 도와주는 곳이라고 느낀다.Q. 최근에는 어떤 디바이스를 만들고 있는가.A. 흔히 인공지능이라고 하면 일종의 어시스턴트를 많이 떠올리는 것 같다. 개인적으로는 이 ‘어시스턴트'라는 것이 너무 범위가 넓고 거대한 느낌이다. 나는 조금 더 작고 가벼운 기술, 그리고 특정한 범위 내에서 나의 일상에 정말 도움을 주는 제품을 개발하고 싶었다. 처음에는 방에 무드 조명이 있는데 ‘이 조명이 좀더 스마트하다면’이라는 생각을 가지고 확장시켜나갔다. 피터팬에 등장하는 “팅커벨”이라는 캐릭터가 생각이 났고 원하는 분위기에 따라서 혹은 알람을 제공하기 위해 예쁘게 불빛을 밝혀주는 것이 초기 모델이었다. 가정에서 인공지능 스피커를 사용하는 사용자들은 스피커를 실상 똑똑하게 쓰지 못하는 경우가 많다. 심지어 꺼놓는 경우도 많이 보았다. 나 또한 구매 초기에는 열심히 사용하다가 요즘은 알람 기능 만을 사용하고 있다. 개인적으로 인공지능 스피커를 잘 사용하지 않는 이유가 현재의 사용성과 음성으로 정보를 전달한다는 한계 때문이라고 생각했다. 스피커는 음성 명령을 잘 알아듣지도 못할 뿐더러, 내게는 스피커의 부자연스러운 음성이 시끄럽게 느껴지기조차 했다. 이런 불편함을 개선하기 위해 무드 조명의 색 조합을 통한 정보 전달을 구상했다. 조명의 색깔로 전달한다면, 스피커처럼 음성이 다 끝날 때 까지 기다리지 않아도 되고, 더욱 빠르고 덜 성가신 방법으로도 정보를 전달할 수 있다고 생각한다. 프로젝트를 구체화하며 조명과 사물인터넷(IoT)에 대해 공부하고, 컨셉을 발전시키다 보니 사물인터넷을 통한 조명 컨트롤이라는 새로운 방향성이 생겼다.사진2. 이주현 님은 다양한 실험을 통해 최적의 디바이스를 개발하고 있다.Q. 스켈터랩스에 어떻게 입사하게 되었는지.A. 어릴 때 부터 아이디어를 내고, 그것을 실제로 구현해보는 다양한 활동을 좋아했다. 학부 시절에는 아이디어를 발제하고 이를 직접 만들어보는 소모임에도 참여하였다. 학부 전공이 전자공학이지만 인공지능 기술에 대한 관심도 컸다. 사실 인공지능은 소프트웨어 분야 아닌가. 그래서 졸업작품을 인공 지능 관련 디바이스로 정했을 때도 소프트웨어 관련 강의를 찾아 들어야했다. 그러다 현재 우리회사 하드웨어 엔지니어 파트의 리더를 맡고 있는 재경님을 만나게 되었다. 처음에는 아이디어를 실현하기 위한 기술 자문을 구하기 위해 뵈었는데, 재경님이 근무하고 계신 회사 얘기를 들으면서 입사에 대한 꿈을 키우게 되었다. 그렇게 우연히 스켈터랩스에 대해 알게된 것 같다.Q. 자발적으로 인공지능 관련 공부를 했다지만, 스켈터랩스에서 일하며 인공지능 기술 회사에 하드웨어 엔지니어로 근무하기가 녹록치않을 것 같다.A. 인공지능 기술을 비롯한 소프트웨어 전반의 공부를 계속 해야하는 것은 맞다. 그렇지만 스켈터랩스는 자발적으로 공부하기 좋은 문화를 갖추고 있고, 자연스럽게 최신 기술을 접할 수 있는 기회도 많다. 너와 나의 일을 규정짓고 나누기보다는, 무엇이든 스스럼 없이 질문하고, 함께 답변을 찾아 가는 분위기가 조성되어있다. 그래서 기술 하나를 물어보면 열을 가르쳐주려고 한다. A를 물어볼 때, 시간이 된다면 A부터 Z까지는 알아서 답변해주는 분위기 같다. Tech-Talk와 같은 사내 세미나를 통해서 강의 형태로 인공지능 기술에 대해 접하기도 한다. 또한 하드웨어 팀 내부적으로도 공부에 대한 필요를 느끼고  자체 세미나를 진행한다. 거창한 것은 아니지만, 우리가 스켈터랩스 기술에 대해 알아야 할 부분을 각자 공부하고 공유하는 자리였다. 이러한 과정이 버겁기 보다는 좋아하는 분야를 더욱 심층적으로 접할 수 있어 좋다.Q. 스켈터랩스에서 일하며 느끼는 좋은 점을 자랑한다면.A. 스켈터랩스는 ‘일단 해보자'라는 분위기가 있다. 아이디어를 내면, 시간과 재화를 제공해주고 시도해볼 것을 권장한다. 작은 실패에 연연해 할 필요도 없다. 해보고 아니다 싶을 때, 그 때 가서 접어도 늦지 않다, 라는 쿨한 문화가 있다. 나와 같이 새로운 것을 생각하고 만드는 것을 좋아하는 이들이라면, 이곳이 정말 이상적이다. 집에서 혼자 하던 것을 ‘일'로서 지원받으며 할 수 있으니까 말이다. 그리고 정말 눈치보지 않는 문화라는 점을 강조하고 싶다. 일하다 지칠 때면 블루룸(스켈터랩스에서 가장 큰 룸인데, 게임방으로 활용되고 있다)에서 게임을 할 수도 있고, 쇼파로 편하게 자리를 옮겨 일하기도 한다. 입사 초창기에 휴가에 대해서 미리 양해를 구하곤 했는데, 그럴 때마다 들은 말은 ‘알아서 할테니 걱정하지 말아라. 휴가썼다고 말도 하지 말고 떠나라' 였다. 이처럼 자율적인 문화에서도 각자 알아서 제 몫을 톡톡히 해내고 있다는 것이 스켈터랩스의 가장 멋진 점이라고 생각한다.Q. 반대로 가장 힘든 점은.A. 아무리 하드웨어 엔지니어 파트에 대한 지원이 있더라도, 우리는 어디까지나 ‘인공지능 기술’ 회사다. 그렇기 때문에 소프트웨어 엔지니어가 훨씬 많고, 프로그램 개발이 회사의 메인 테스크(Main Task)로 인식될 때가 많다. 전자공학을 전공했는데 인공지능 회사에 다닌다고 하면 의아해 하는 엔지니어들도 많다. 하지만 최근 하드웨어 단에서 인공지능을 작은 저전력 디바이스에 옮기려는 연구는 계속해서 진행되고 있다. 소프트웨어팀이 멋지게 구현한 어플리케이션 등의 서비스를 100퍼센트 전달할 수 있는 디바이스를 만드는 것을 목표로 하고 있다.사진 3. 스켈터랩스의 블루룸에는 각종 게임이 구비되어있고 밴드부 연습실로 활용된다.Q. 스켈터랩스에서 업무 외에 어떤 활동을 하고 있나.A. 밴드, 축구, 헬스동아리까지 하고 있다. 취미가 음악이라 대학교 때부터 밴드부로 활동했는데, 그때마다 공간의 필요성을 절감했었다. 악기 대여비도 만만치않게 들지 않나. 스켈터랩스 밴드인 Terkels는 공간과 악기를 모두 갖추고 있다. 심지어 PA(Public Address) 앰프와 공연용 스피커까지 구비되어 있다. 축구 동아리에서 매주 1회 풋살 대결을 펼치고, 점심 시간마다 헬스 동아리원들과 함께 헬스장에 간다. 이렇다보니 부모님한테 ‘놀려고 회사가냐'라는 핀잔을 들을 정도다.Q. 많은 동아리와 업무를 병행하는 것이 힘들지는 않은가.A. 전혀. 오히려 동아리 활동으로 더욱 친해진 팀원과 함께 머리를 맞대고 하는 업무이다보니 ‘일'이 아니라 일종의 ‘놀이'처럼 인식될 때가 있다. 그리고 스켈터랩스 특유의 문화가 겉으로는 느릿느릿 여유롭더라도 내부적으로는 치열한 부분이 있다. 축구동아리에 처음 참여했을 때 동아리원들이 ‘살살 뜁시다' 하더니 막상 경기 시작되자마자 엄청나게 공격적이더라. 살살 뛰는 사람은 한 명도 없었다. 무섭게 뛰고 공격하면서 골이 계속 터졌다. 헬스동아리는 최근에 생긴 동아리다. 여름맞이 몸을 만들기 위해서 여럿이 뭉쳐서 헬스장을 함께 간다. 헬스 자체가 함께 할 수 있는 운동은 아니지만, 그래도 시간을 정해서 함께 이동하다 보니 ‘오늘은 좀 운동하지말고 먹을까' 싶다가도 다른 분들이 가면 자극을 받게 되고, 더 열심히 운동하게 되더라. 일도 마찬가지다. 처음에는 ‘회사가 이렇게 놀게 해줘도 되나'했지만, 내부적으로 탄탄하게 서로 함께 놀고 일하며 자극과 영감을 받는 문화다.회사는 딱히 데드라인을 촉박하게 주지도 않고, 압박을 하는 경우도 없다. 그런데 다들 게임방에서 신나게 게임을 하다가도 다음 날이면 개발을 마친 결과물을 들고 온다. 자율적이지만 확실하게 자신의 업무에 대해 책임을 지는 문화가 형성되어 있다. 그렇다보니 나 또한 자연스럽게 동아리 활동을 하다가도 오늘 하루 내가 끝내야할 일로 정해놓은 것들은 마치고 퇴근하려 한다.Q. 회사에 게임방이라니, 게임방 얘기를 듣고싶다.A. 게임을 좋아하는 사람들이 많다 보니 닌텐도를 비롯해서 엑스박스(Xbox), 플레이스테이션(Playstation)을 비롯한 각종 게임기가 마련되어 있다. 다트와 탁구대, 당구대까지 준비되어 있다. 사무실을 성수로 이사하면서 테드님(Ted Cho, 스켈터랩스의 대표인 조원규 님은 사내에서 테드님으로 불린다)이 ‘모두가 놀 수 있는 공간을 만들겠다'라고 했었는데, 정말 놀이터를 만들어주시더라. 덕분에 점심시간마다 삼삼오오 모여서 각종 게임과 탁구, 당구를 즐기고 있다.Q. 하드웨어 엔지니어로서 최종 목표가 있다면.A. 테드님이 우리에게 자주 하는 말 중 하나가 ‘Don’t be evil’이다. 이 말은 사실 구글의 모토인데, 스켈터랩스의 모두가 공감하는 얘기다. 기업이 이윤을 추구할수록 소수에 대한 외면이 발생하기도 하고, 기술 기업으로서 수익 창출 만을 목표로 하면 정작 일상을 어떻게 더욱 편리하고 윤택하게 만들어줄 수 있는지를 쉽게 망각하는 것 같다. 사악해지지 않으면서, 정말 우리의 삶을 나아지게 하는 방법을 계속해서 고민하고 싶다.#스켈터랩스 #사무실풍경 #업무환경 #사내복지 #기업문화 #팀원인터뷰 #팀원소개 #팀원자랑
조회수 1050

Team Profile: Meet Yonghyun

Read In KoreanAs a yet minuscule startup, each member holds a significant power over the overall atmosphere of the team. And in our ultimate quest to make big waves in the data world, we need to make sure that the people at the helm are at least kind of cool. We think we’ve done a pretty good job so far in assembling a society of unique but equally driven members.So we bring you this seven-part series, one of each devoted to interviewing each of our members in detail, to give you an in-depth glimpse into the people responsible for bringing you the future of machine learning with Daria. Plus, we peppered the interviews with questions from Dr. Aron’s “The 36 Questions that Lead to Love”*, cherry picked to make work appropriate and concise, but interesting.(*actually falling in love with our members highly discouraged)Yonghyun joined the XBrain team in August as a software engineer, and has worked closely with other members in constructing the software that Daria runs on. But his interests run beyond just making sure that Daria become the future star of machine learning and data science — Yonghyun is also an avid soccer player, and an enthusiastic dabbler of virtual and artificial reality. Learn more about him here!Yonghyun saves a few minutes of his day for some introspection/staring broodily out the windowHi Yonghyun! Start by telling us about your role.YH: I work with JM as a software engineer at XBrain, developing and testing our software infrastructure.How do you usually spend a work day?YH: I usually come to work around lunchtime, and devote my time to whatever needs to be done for the day. Today we worked on tests involving transferring data from MS SQL. I enjoy afternoon walks sometimes, and usually head home after working a little post-dinner.Tell us about the parts of your job that you most enjoy.YH: I enjoy transforming machine learning modules into Spark to fit with the cloud system, and looking at the code Suzin’s written in order to understand the process.What about the aspects that you least enjoy or find challenging?YH: Setting up the environment to test our systems is something I least enjoy. It’s frustrating, because you can follow all the steps and still go the wrong way.Pick one item on your desk that tells us something about you.YH: I don’t have a whole lot on my desk…so I would probably have to say my laptop. The very very big laptop provided to me by the company.Laptop in photo is larger than it appearsWhat made you want to become a software engineer?YH: I was originally majoring in History in college, but I was struck by how computer science could help you create something tangible. Programming helps turn your ideas into reality on the screen, which is something I was really drawn to.So why XBrain?YH: As an incoming programmer, you don’t really come across the opportunity to participate in the making of a product that’s still under development. It’s a good learning experience for me to watch Daria’s progress. Furthermore, because I started programming at a relatively later stage, I still need help with my mathematical background, which working here allows me to do.As the one of the newest additions to the team, tell us about your vision for XBrain.YH: I think my vision is one of becoming a household name for a machine learning tool that a lot of people use on the daily — Daria doing useful things in every facet of the world, big or small.What is your go-to work playlist?YH: When I’m coding, I usually prefer EDM, so stations like Hardwell On Air, and hip-hop as well.Recommend a movie for our next Cinema Society, please.YH: Watchmen (2009). Its protagonist Rorschach is an anti-hero, and the plot line is complex and interesting to follow.Where do you see yourself 10 years from now?YH: Career-wise, honestly I wouldn’t mind what I have right now — working a job that I love without getting too swamped with deadlines, with plenty of time for exercise and socializing, playing soccer with my friends.Given the choice of anyone in the world, whom would you want as a dinner guest?YH: Mark Zuckerberg, maybe? I’d like to hear about his ideas for the future.If you had to have dinner with one XBrain member, who would it be and why?YH: JP, our new machine learning engineer. I’d like to get to know him better, and he seems like an interesting person.Would you like to be famous? In what way?Nope.What would constitute a “perfect” day for you?YH: A day productive enough that I could go to bed without worrying about the next day.If you were able to live to the age of 90 and retain either the mind or body of a 30-year-old for the last 60 years of your life, which would you want?YH: The body of a 30 year old… I don’t think that youth isn’t everything when it comes to minds.For what in your life do you feel most grateful?YH: The privilege to have been able to learn and achieve everything I’ve wanted is something I’ll always be thankful for, and also the flexibility to be able to change directions I’m headed in.If you could wake up tomorrow having gained any one quality or ability, what would it be?YH: I’ve always wanted more drive to carry out the projects I’ve devised in my head, the ability to see things through no matter what.Is there something that you’ve dreamed of doing for a long time? Why haven’t you done it?YH: I’ve always wanted to learn how to cook. I lived in a dorm in college so I didn’t have the opportunity then, but now would be a good time as any.What is the greatest accomplishment of your life?YH: I would say my greatest accomplishment is putting my best efforts into learning and improving my mind, inside and outside of school.What is your most memorable XBrain moment?YH: My fondest memories are usually of events we held outside — the hike we went on in September, or the soccer game we had. I like that we got to bond as a team and get some exercise.If you knew that in one year you would die suddenly, would you change anything about the way you are now living? Why?YH: I haven’t been able to get decent sleep recently, so I’d probably give myself some time to rest.If you were going to become close friends with someone, please share what would be important for him or her to know.YH: I don’t have very strong likes or dislikes, so I usually get along with most people.What, if anything, should never be joked about?YH: You should never joke about the disadvantaged, or others’ insecurities.If you could sum up XBrain in three words or less?YH: Freedom. Consideration. Learning…. Is that too serious?#엑스브레인 #팀원소개 #팀원인터뷰 #기업문화 #조직문화 #팀원자랑
조회수 889

로봇 택시가 산업 지형을 바꾼다

로봇 택시가 산업 지형을 바꾼다"자율 주행 전기차의 등장으로 유가가 배럴당 25달러까지 떨어지고, 새로운 세계 질서가 도래할 것이다."'에너지 혁명 2030' 의 저자로 2015년 한국을 방문한 적 있는 토니 세바 스탠포드대 교수(RethinkX의 공동 설립자)가 최근 미국 CNBC와 인터뷰에서 "기름 수요가 2020년~2021년 사이 1백만 배럴로 꼭지를 찍은 뒤 10년 내(2030년경)로 70만 배럴까지 줄어들면서 유가가 하락세를 면치 못할 것”이라며 이같이 예견했다.점차 많은 사람들이 공유경제의 축으로 자율 주행 전기차를 사용하게 되면서 ▽오일 회사는 생존이 어렵게 되고 ▽심해, 세일가스업체와 정유 파이프라인 회사들도 문을 닫게 될 것이라는 게 그의 예측이다.차량도 소유의 대상에서 서비스의 대상, 이른바 TAAS (transport as a service) 로 바뀐다. 차량을 더 이상 구입하지 않고, 편리하게 앱으로 로봇 택시를 호출해 이용하면 그만이다. 자율 주행 전기차의 가격도 싸지면서, 전기차 이용이 소유에 비해 10배 정도 저렴해질 것이라는 것.  경제학자인 그의 섬뜩한 전망은 계속된다. 급속한 기술의 진보로 인해 값비싼 정유회사나, 적응력이 떨어지는 카 메이커(의 주식)가 매력이 없어지며, 차량과 관련된 직업 중에서 차 딜러도 2024년까지 사라질 것이라는 예상이다.뿐만 아니라, 주차공간의 80% 이상이 쓸모없게 되고, (자동차)보험의 비용도 급격하게 떨어지기 때문에 보험회사도 설 땅이 좁아진다는 것.이 같은 그의 전망이 혼자만의 견해는 아니지만,  다른 사람들은 이런 변화에 훨씬 많은 시간이 걸리고, 그렇게 극적이지도 않을 거라고 내다본다.반대로 그는 차량 관련 지출이 줄면서 가계 소비가 늘어나 경제성장을 촉진할 것이라고 예상했다. 아울러 차세대 차의 개발과 관련된 차 운영체제, 컴퓨터 플랫폼, 배터리, 지도 소프트웨어 회사들을 눈여겨 보라고 조언했다.세바 교수의  유가 하락 전망이  결코 급진적인 것은 아니다.  유가는 WTI(서부 텍사스중질유)기준으로 2016년 2월에  배럴당 20달러대 중반까지 급락한 바 있다.  6월 14일 현재는  40달러대 중반에 머물러 있다.다만, 차량이 소유의 대상에서 이용 서비스의 대상으로 바뀐다든지, 차 딜러가 사라진다든지 하는 등의 혁신적이거나 과격한 전망이 실현될 지는 두고 볼 일이다.참조 : 다음은 토니 세바 교수가 참여한 화제의 보고서 ‘Rethinking transportation 2020-2030’ 원문 링크https://static1.squarespace.com/static/585c3439be65942f022bbf9b/t/591a2e4be6f2e1c13df930c5/1494888038959/RethinkX+Report_051517.pdf
조회수 1824

잔디의 새싹 같은 안드로이드 개발자 Gary를 만나다.

맛있는 인터뷰 : 안드로이드 개발자(Android Developer) Gary 편집자 주잔디와 함께 하는 멤버는 총 35명. 국적, 학력, 경험이 모두 다른 이들이 어떤 스토리를 갖고 잔디에 합류했는지, 무슨 일을 하고 있는지 궁금해하는 분들이 많습니다. 잔디 블로그에서는 이 궁금증을 해결해 드리고자 ‘맛있는 인터뷰’를 통해 ‘잔디’ 멤버들의 이야기를 다루고 있습니다.인터뷰에서 가장 기초적인 질문. 예상하신 자기소개 부탁한다.G : 잔디 개발자 중 제일 어린! 핵심 키워드다. 강조 부탁한다. 가장 어린! 안드로이드 플랫폼 개발을 맡은 Gary다(이하:G). 잔디 입사한 지는 9개월 되었다. 특별한 일 없이 정말 열~! 심히 개발만 했다. 일주일 전부터 식당 선택을 강요(?)했다. 이 식당을 선택한 이유는 무엇인가?G : 음식이 푸짐하게 나오기도 하지만 조명이 좋다. 인터뷰 중 사진을 찍는다고 들었는데 그 사진이 예쁘게 나올 것 같아서 선정했다. 게다가 음식이 정갈하다. 안에 룸도 있어서 회식하기도 좋다. 내 입이 복잡하질 않아서 뭘 먹어도 다 맛있다. 어차피 다 맛있는 거 사진이라도 잘 나와야 한다 싶어서 선택하게 되었다. 잔디에 들어오게 된 계기는?G : 모집 공지가 뜨길래.. 농담이다^^; 전 직장과의 시스템이 다른, 자체 서비스를 하는 회사에 가보고 싶었다. 전 직장에서는 기획, 서버, 디자인, 개발을 각각 다른 회사에서 진행했다. 내가 속한 회사는 개발만 진행했다. 처음부터 끝까지 한 곳에서 서비스하는 회사를 가보고 싶었다. 또한, 기술 스택이 너무 좋았다. 이를 통해 앞으로 나의 실력이 일취월장할 수 있겠다는 생각이 들었다. 9개월 동안 많이 발전한 것 같은가?G : 상당히 많이 발전했다. 어떤 부분에서 발전한 것 같은가?G : 이전 회사에서는 일정에 쫓기다 보니 개발 자체에서 설계라는 게 없었다. 손 가는 데로, 일단 만들고 보자라는 식으로 신기술이고 뭐고 공장처럼 찍어내는 것이 일이었다. 하지만 잔디는 다르다. 2주 단위로 생각을 통해 설계도 해보고 ‘객체지향 설계 5대 원칙’ 등 다양한 사항을 고려해보며 많은 고민 끝에 개발하는 것이 너무 좋다. 이를 통해 개발자로서 더욱 성장한 것이 느껴진다. 이전 회사보다는 일찍 퇴근하는 편인가?G : 이전 회사는 철야, 야근 거의 매일 했다. 입사한 지 9개월 정도 되었는데 이제야 사람답게 사는 것 같다. 그동안은 짐승인 줄 알았다. 일어나면 출근하고 퇴근하면 자고. 9개월 동안 사람답게 살면서 잠도 푹 잤다. 몸이 편해지면 사람 얼굴이 확 산다고 하던데 생긴 건 나아지지 않더라. 옛말도 틀린 말이 있나 보다. (하하) 주말엔 뭐하시는가?G : 집돌이 성향이라 집에 있는 경우가 많다. 밖에 나가면 이웃 주민들과 소통하기도 한다. 지금 사는 곳은 취업한 지 얼마 안 된 사회초년생들에게 국가에서 주는 ‘행복주택’이라는 곳이다. 그곳엔 대부분 사회초년생이라 연령대가 20대 후반에서 30대 초반 정도 된다. 그분들과 소통을 하며 지내고 있다. 나이가 비슷하니 공감대 형성도 되고 행복주택에서 행사 같은 걸 많이 해서 문화생활 영위하는 듯하다. 말 그대로 사람 사는 듯한 느낌이다. 서울 집값이 너무 비싸다. 행복주택은 저렴한 편인가?G : 다른 원룸에 비교하면 저렴한 편이다. 보증금이 들어가지만, 월세는 10만 원 전후다. 서울에서 월세 10만 원 전후라면 저렴한 편 아닌가? 사회 초년생분들께 추천한다. 이웃들도 좋고 문화생활도 하고. 엄청나지 않은가? 신청 후 당첨이 되어야 하지만 당첨되기 쉬운 편이다. 꼭 한번 도전해봐라. 처음 들어왔을 때 잔디는 어땠는가?G : 사실 처음 들어왔을 때 사무실이 시끌벅적하며 소통이 아주 활발할 줄 알았다. 그런데 딱 들어오니 어?! 음? 오?!… 조용하다. 진짜 활발한 곳은 따로 있었다. 목소리가 아닌 손가락으로 얘기하는 곳. 잔디 앱이었다. 사무실 자체는 너무 조용한데 잔디 앱 안에서 매우 활발하다. 아이러니하지만 의사소통은 아주 활발했다. 잔디의 생활 중 가장 마음에 드는 문화는?G : 영어 이름을 사용하며 상호 간에 존중하는 문화다. 30년 동안 한글 이름으로만 살았는데. 회사만 오면 Gary라고 부른다. 첨엔 이게 날 부르는 건지도 잘 몰랐지만 익숙해지니 너무 좋다. 수평적인 관계의 시작이 무엇인지 알게 되었다. 이전 회사와는 다르게 잔디에서는 수평적인 관계여서 의견 개진이 편했다. 의견을 나눌 수 있다는 것이 너무 좋았다. 물론 손끝으로 얘기하지만:D 감정표현도 이모티콘으로 한다. 표정은 무표정이지만 손가락은 웃고 있달까? 내 얼굴은 무표정인데 프랑키 (파랑몬스터 캐릭터)가 웃어준다. 이젠 오프라인으로도 소통이 되었으면 한다. 사무실 밖에선 말이 많으신 분들인데. 사무실만 들어오면 조용하시다. 손으로 말하고 계시니까. (웃음) 회식은 자주 하는가?G : 팀마다 다른 것 같다. 팀 내에서 석 달 치 회식비를 모아서 한 번에 하던가 쪼개서 자주자주 하던가. 어차피 쓰는 돈은 같으니까. 이루고 싶은 꿈이 있다면?G : 백수가 되고 싶다. (비장) 충분한 불로소득이 있는. 소득과 상관없이 내 맘대로 살 수 있는 그런 백수가 되고 싶다. 회사를 가고 싶으면 회사를 가고 사업을 하고 싶으면 사업을 하는 그런 백수(하하). 사실 프로그래머로서 직업을 정했을 때는 최고의 프로그램을 만들어보는 게 꿈이었다. 또한, 안드로이드로 시작했으니 구글에서 종지부를 찍자! 이런 꿈을 꾸었다. 그런데 이전 직장이 너무 힘들었나 보다. 꿈이 변했다. 백수로. 하루는 7개월 정도 만에 칼퇴근하고 집에 갔더니 어머니께서. “너 잘렸냐?”라고 물어보시더라. 그땐 내 회사 생활에 문제가 있구나 싶었다. 백수는 아니지만 일과 삶의 밸런스가 맞는 삶을 살고 싶다. 다음 인터뷰어에게 하고 싶은 질문이 있나?G : 회사 내에 다른 팀원들과 지금 먹고 있는 음식을 같이 먹을 수 있다면 누구랑 같이 먹고 싶은가?#토스랩 #잔디 #JANDI #팀원소개 #인터뷰 #기업문화 #조직문화 #사내문화 #팀원자랑
조회수 836

블록체인 진짜 하나도 모르는 디자이너의 독학일기(1)

독학을 시작했습니다. 스터디를 가려고 했는데 수많은 전문용어들이 제 영혼을 피폐하게 만드는 바람에 정신건강이 염려되었거든요. 포토샵도 혼자 배웠으니 이것도 못할까! 라고 자신있게 책을 폈는데 못할 것 같습니다.......그래도 산 책 값이 아까우니 읽고 공부한 내용들을 하나하나 정리해보고자 합니당! 블록체인 전문가님들이 혹시 이 글을 보신다면 노잼과 지루함내지는 유치함을 느끼실 수 있으니 엄빠미소로 지켜봐주시면 감사하겠습니다. 잘못된 부분이 있다면 바로 잡아주세요!!글을 쓰면서 5가지 원칙을 지킬겁니다.1. 꼭 써야하는 고유명사가 아닌 이상 어려운 단어는 쓰지 않습니다. 중학생 정도가 이해될 수준이길 제발 바랍니다...저는 블록체인을 이제 이틀 째 공부하고 있거든요.2. 가급적 팩트체크된 내용만 쓸겁니다.3. 제대로 공부하려면 경제사, IT기술, 코딩 등등..수많은 요소가 복잡하게 들어가지만 여기선 꼭 필요한 쏘옥 뽑아서 얘기할 겁니다. 4. 짧게 쓸 겁니다.5. 가끔 쓸 겁니다.(자주 쓰기 힘든 주제임..)시작합니당 :)블록체인이 왜 태어났는지 얜 뭔지부터 알아야 할 것 같아요. 그러자면 시간을 조금 되돌려서 우리는 어떻게 사고파는 경제활동을 해왔는지 살펴볼께요.1. 아주 오래전 = 기억하기종이란게 나타나기도 전 우리는 사과5개를 빨간집에서 해가 질 무렵에 씨앗10개와 교환했다. 는 걸 기억해야 했어요. 문제는 서로가 잘못 기억하거나 한 쪽이 다르게 우겨버리면 할 말이 없다는 거죠..철저히 신뢰와 기억에 의존한 거래였어요.2. 오래 전 = 나무나 가죽에 새기기원래 사람은 두 발로 직립보행 하기 전부터도 그림을 좋아했어요. 동굴에도 그리고 돌에도 그리고, 나무나 땅에도 곧잘 그림을 그렸죠. 뭔가 주고받는 물품이 많아지면서 기억하기가 힘들어지자, 이젠 가죽이나 나무 등등에 갯수를 남기기 시작했죠. 문제점은 그 가죽이나 나무가 훼손되거나 도난당하면 증명할 방법이 없다는 거에요.'동쪽 언덕 마을에서 온 또박이가 가죽3개를 사갔다.'3. 조금 오래전 = 종이에 적기(단식부기)종이가 발명되고 아라비아 숫자와 알파벳, 한글, 한자, 인도어 등등이 발달하기 시작하면서 문서를 남길 수 있게 되었어요!!! 문서를 남긴다는 건 굉장했죠!!!오랜 시간이 지나도 기록들을 잘 보관할 수 있었어요!! 거래를 할 때에도 수입과 지출을 한 번에 (가계부처럼) 적으면서 작은 종이에 많은 내용을 남길 수 있었답니다. 하지만..여전히 문제는 사람이었어요. 이를 위조하거나 없애버리면...? 또는 불에 다 타서 없어지면??4. 얼마 전 = 적은 걸 나눠가지기(복식부기)그래서 서로 함께 같은 내용을 공유하기로 했어요. 너 하나 나 하나. 그리고 그 과정을 감시하는 회계사. 이런 과정은 우리 조선시대에서도 아주 엄격했답니다. 특히 계문화가 발달했던 우리나라는 다양한 장부를 기록했는데 '용하기'라는 계의 장부기재는 정말 엄격한 원칙이 있었답니다!!1. 임시장부를 2부 작성해요. 이 때 회계담당자 이외 심지어 2명이 더 감시하고 있어요.2. 기재를 시작해요.3. 계원들이 다 모여야 하고 적은 내용을 크게 읽어요. 이 때 의심스러운게 있으면 이의제기나 수정을 해요.4. 계장과 두 명의 감시원이 있는 상태에서 최종수정해요. 그리고 계장이 서명해요.5. 중복된 장부가 있는지 확인하고 새 장부를 넣어 보관해요.엄청나죠???..놀라운 건 현재의 블록체인의 원리도 위와 비슷해요!! 다만 사람이 일일이 적고 감시하는 게 아니라 명령어에 의해 챡챡 처리되는 것 뿐이랄까요. 하지만 이것도 결국 '물질' 이다 보니....화재나 전쟁으로 인해 소실되어 버리면 그걸로 끝이었어요.5. 요즘 = 기관이나 중앙에 맡기기왕정체제가 아니라 민주주의와 시장경제가 도입되면서 은행이나 보험사, 카드사와 같이 경제활동을 담당하는 기업과 중앙기관이 생겨나기 시작했어요! 엄청나게 거대한 정보를 크으으은 서버나 금고에 보관할 수 있었어요. 그것은 영원해보이고 사람들은 오래도록 보관할 수 있다고 생각하니 관심을 끄기 시작했죠. 내 돈은 금고에 잘 있을 거니까요.하지만, 자본주의는 그런게 아니었어요. 은행은 내 돈을 다른 사람에게 대출로 빌려주고 그 이자로 돈을 벌어요. 그리고 다른 사람이 갚은 돈으로 다시 내 예금을 채우죠. 졸라 돌려막기인 거에요. 사람들이 끊임없이 돈을 빌리고 다시 갚을 수 있게 다양한 상품들을 만들어요. 이 방식은 굉장히 효율적이고 아무 문제가 없을 것 같이 보였어요.하지만, 해킹을 당했어요.은행을 털렸어요서브프라임 모지기론 사태처럼, 무리한 상품의 실패는 수백개의 기업을 무너뜨렸어요. 수많은 사람들의 돈이 한 순간에 날아갔어요.서버가 먹통이 되어 거래가 안되는 경우도 있어요.지진 등의 천재지변이 나면 내 기록은 사라지고 말아요.단순히 큰 사옥을 지닌 곳이니까 영원불멸할 것 같았던 중앙기관도 하루 아침에 무너질 수 있단 사실을 우린 수 차례 경험했어요. 그럼에도 우린 뭘 어떻게 해야할 지 몰랐어요. 우리가 할 수 있는 건 사고가 터지면 변호사를 써서 소송을 하는 것 뿐이었어요. 우린 은행의 상품이 정확히 어떤건지, 보험약관이 뭔지... 카드사는 어떤 원리로 움직이는지...내 세금은 어떻게 쓰이고 있는지...우리 돈이 어떻게 거래되고 내 돈을 가지고 그들이 무엇을 하는지 하나도 몰라요. 그냥 속수무책으로 그들만 믿고 있는 거예요. 6. 블록체인의 탄생 = 모두가 장부를 가질 수 있게그래서 생각해봤어요. 한 곳에 모여있으니 문제가 생긴다면, 쪼개면 되지 않을까? 은행 한 곳을 터는 것은 쉽지만 1,000여명을 한꺼번에 터는 것은 불가능할테니까. 계모임에서 쓰던 그 장부를 엄청나게 많이 만들어서 모두가 가지면 어떨까? 누굴 못 믿거나 위조하거나 털리거나 불나서 사라질 일이 없을 거 아냐?? 라는 생각을 말이죠. 그런데 친구가 질문을 하네요!!친구 : 그런데 어떻게??나 : 인터넷이 있잖아!! 내가 온라인상에서 거래하면 그 기록이 남잖아~ 그걸 모두가 공유하는거지! 친구 : 모두가 누군데?나 : 응 그건 이제부터 모아야해!!친구 : 그럼 어쨌든 모인 사람들에게 모두 공유하면 내가 어제 김치한포기 시킨것도 다른 사람이 알게 되는거야??나 : 아니지;;; 니가 뭘 시켰는지 그딴 건 관심없어..그냥 얼마 거래를 언제 몇시몇분몇초에 어떻게 했는가만 기록에 남는거야! 그리고 다른 사람은 그걸 직접 눈으로 볼 수 있는 게 아냐.생각해봐. 넌 브런치 로그인한 기록을 눈으로 다 볼 수 있어? 며칠 몇시에 얼마나 로그인했는지 알 방법이 없지? 하지만 그 기록이 있을까 없을까? 그렇지, 반드시 있다구. 범죄수사할때도 그러자나. 우리 화면에는 시간/내용밖엔 안뜨는 문자메시지지만, 실제로 서버에는 발신위치, 수신위치, 번호정보 등등이 모두 숨겨져 있잖아. 또 하나! 너가 네이버에서 틴트를 검색하면 나중에 페북에서 틴트광고가 뜨지 않아? 우리의 방문기록이나 클릭한 기록들이 모두 남아있기 때문이야.이렇게 우리가 눈으로 보는 화면 뒤에는 수많은 정보들이 컴퓨터만의 전기신호로 저장되어 있어. 우리가 말하는 장부도 이런 식으로 저장되어 있는거라구.  물론 필요하다면 그걸 화면으로 띄울 수 있는 명령어를 만들 수도 있겠지.친구 : 그건 이해했어, 내가 직접 볼 순 없지만 마치 사이트 방문기록처럼 어딘가에 거래내역이 다 남아있다는 얘기지?... 그런데 아까 지금부터 모아야 한다는 사람들은 어떻게 모으는거야??나 : 그건!!..바로!!!! 다음에 설명해줄께!!또 공부해서 돌아올께용!!
조회수 1518

CTO의 인간선언

아이오에서 일 한지 어느 덧 한 달 가까이 되어간다.이젠 나도 어느 정도 팀의 비즈니스 로직, 도메인, 문화, 사용하는 기술들이 조금씩 이해되기 시작하고 있다.그러자 이번엔, CTO이자 나의 멘토이며 사수인 미정님이, "직접 기능을 하나 TDD로 개발해서 Pull Request 해보라"는 미션을 주었다.API를 보고, 구글링하고, 기존에 미정님이 짰던 코드를 참고해서 만들어갔다.그럼에도 불구하고 제대로 작동하지 않는 코드가 있었다.혼자 해볼 수 있는 것은 다 해 본것 같은데도 해결법이 떠오르지 않아, 미정님에게 이런저런 문제가 있다고 설명하고 도움을 요청했다.미정님이 코드를 좀 보더니 해결했다. 미정님이 짰던 기존 코드에 오류가 있었고, 내가 그것을 참고해서 코드를 짰기 때문에 생긴 문제였다.그녀는 쓴 웃음을 지으며, “변형덕에 오류발견 했네, 잘했어.”라고 약간 주눅들어 말했고,나는 “아, 저는 미정님 코드는 완벽하다 생각하고 그걸 레퍼런스로 하고 코드를 짰는데, 그래서 오류를 못 찾았나봐요.”라고 대답했다.그러자 그녀는 갑자기 눈빛을 바꾸며 역정을 냈다. “그건 변형이 아직 엔지니어의 마인드를 못 갖췄다는 말이야!”예상치못한 임기응변에 순간 나는 움찔했고, 내게 유리했던 분위기를 뺐기고 말았다.그녀의 설명이 이어졌다.“세상에 실수 없는 사람은 없어! 엔지니어라면, 컴퓨터는 믿어도 사람은 못 믿는 다는 생각을 갖고 있어야 되!나는 선배가 짠 코드라도 안 믿어. 심지어 구글러가 짠 코드도 난 안 믿어!100%완벽한 코드는 없어.우리가 TDD를 하는 것도 실수나 오류를 최소한으로 줄이기 위해서지, 그렇게해도 오류없는 100% 완벽한 코드를 보장하지는 않아.그러니까 누가 짠 코드든 완벽하다고 생각하면 안 돼! 내 코드도 마찮가지고!”구구절절이 맞는 말이다.친절한 미정님은 스스로를 실수할 수 밖에 없는 인간으로 낮추면서까지, 엔지니어로서 가져야할 자세를 알려주셨다.진정한 살신성인의 멘토라고 아니할 수 없다.ㅜ친절한 박미정줄여서 친박.앞으로 친박이라 부르고 싶다.#스위쳐 #Switcher #개발자 #스타트업 #스타트업CTO #CTO #개발일지 #경험공유

기업문화 엿볼 때, 더팀스

로그인

/