Go – nil, 0, and “”

Go언어로 작성하는 도중 까다로운 부분 중 한 가지가 NULL상태를 체크하는 것이다.

우선 데이터 타입별로 비어있다는 것을 뜻하는 NULL상태는 다음과 같다.

  • int: 0 (Number zero.)
  • string: “”
  • etc.: nil

여기까지는 아무런 문제가 없다. 그러나 다음과 같이, json으로부터 데이터를 읽어들이는 경우를 가정하여 보자. 아래과 같은 struct가 정의되어 있고..

 

type Member struct {

ID      int   `json:"id,omitempty,string"`

Name   string   `json:"name,omitempty"`

Company string   `json:"company,omitempty"`

}

다음과 같은 json을 읽어들인다고 가정을 해보자.

{ id: 500, name: "John Doe", company: "FreakOut" }

이럴 경우는 큰 문제없이, Member.ID == 500,Member.Name == "John Doe", Member.Company == "FreakOut" 가 될 것이다.

다음의 경우는 어떨까?

{ id: 0, name: "", company: "" }

이 경우는,Member.ID == 0,Member.Name == "", Member.Company == ""가 될 것이다.

그렇다면 다음의 경우는??

{ }

이 경우에도 위에 선언된 Member struct대로라면, Member.ID == 0, Member.Name == "", Member.Company == ""가 된다.

좀전의 Json과 같은 결과다. 이 말은 ID의 값이 0것과 NULL(없는) 경우가 같은 값으로 처리가 된다는 말이며, Name과 Company의 경우는 ""와 NULL이 같은 값으로 처리가 된다는 것이다. 큰 문제가 아닐 수도 있지만, 다음과 같은 경우에는 분명히 문제가 될 것이다.

  • 철수는 영희로부터 멤버들의 정보를 모으고자 하는데, 이것을 Json으로 모아서, Member struct로 받고자 한다. 그러나 철수는 영희가 보내는 Json의 모든 정보를 신뢰할 수는 없다고 판단하여, 정보가 누락되어 오는 경우는 받지 않고자 한다. 그리고 영희로부터 멤버들 중 소속이 없는 사람이 있다는 정보를 입수하여, 그런 사람은 company를 “”로 보내기로 영희와 합의하였다.
  • 철수는 명단을 확인하던 중 영희가 보낸 멤버 중, 절대로 있을 수 없는 “John Invalid”라는 이름을 발견하였다.
  • 철수는 이상해서 로그를 확인하는 도중, 다음과 같은 Json을 발견하였다.
  • { id:999, Name: “John Invalid” }
  • Json상에는 company 가 오지 않았는데, 시스템에는 Member.Company에는 “”가 입력되어, 무소속이라고 입력을 받았다고 되어있다.
  • 무소속과, 정보의 누락. 철수는 이 두 가지를 어떻게 하면 구분을 할 수 있을까?

철수가 겪는것과 같은 문제를 실제 프로젝트상에서도 겪을 일이 있을 것이다. 0이나 ""가 어떤 의미를 갖는 값이 된다면 nil과 구분을 해주어야 하는데, int와 string에서는 지원하지 않는다. 그렇다면 이 두가지 외에 다른 자료형을 쓰면 해결이 되지 않을까?

그래서 이럴 경우에는, 포인터형으로 사용하면 되겠다. (*int, *string).

다음과 같이 Member struct의 선언을 바꾸어보자.

type Member struct {

ID        *int   `json:"id,omitempty,string"`

Name      *string   `json:"name,omitempty"`

Company   *string   `json:"company,omitempty"`

}

위 경우에, 다음과 같은 Json을 받는다면….

{  name: "" }

Member.Id, Member.Company는 nil값이 들어갈 것이고,

Member.Name에는 주소값이 들어가고, *Member.Name에는 “”값이 들어갈 것이다. 같은 데이터형인 Member.Company와, Member.Name이 nil과 “”로 구분을 할 수 있다는 것을 확인 할 수 있다.

이 때, 주의해야될 사항은, *Member.Id, *Member.Company를 access하고자 하면 nil값의 참조로 panic을 일으키므로, 포인터형에서는 nil의 체크가 필수라고 할 수 있겠다.

Advertisements

gRPC Load Balancing on Kubernetes without Tears

ref: https://kubernetes.io/blog/2018/11/07/grpc-load-balancing-on-kubernetes-without-tears/

 

Why does gRPC need special load balancing?

  • because gRPC is built on HTTP/2, and HTTP/2 is designed to have a single long-lived TCP connection,
  • it reduces the overhead of connection management
  • Connection balancing doesn’t work well -> Once the connection is established, there’s no more balancing to be done. All requests will get pinned to a single destination pod,

On http/1.1?

  • In contrast to HTTP/2, HTTP/1.1 cannot multiplex requests. Only one HTTP request can be active at a time per TCP connection.
  • Therefore, to have concurrent HTTP/1.1 requests, we need to make multiple HTTP/1.1 connections and issue our requests across all of them.
  • Additionally, long-lived HTTP/1.1 connections typically expire after some time and are torn down by the client (or server).

How do we do on gRPC?

  • In network terms, this means we need to make decisions at L5/L7 rather than L3/L4, i.e. we need to understand the protocol sent over the TCP connections.

On Kubernetes?

Machine learning meetup @Google Tokyo Office 2017/11/29

2017/11/29 Google 도쿄 오피스에서 개최된 Machine learning meetup 에 다녀왔다. 사실 전설의 Jeff dean이 등장한다기에 무작정 신청을 해서 가봤다. 뒤늦게나마 내용을 정리해보았다. 사실 딥러닝이나 Tensorflow를 이용할 일이 거의 없어서 내용 이해에 어려운 부분도 있었지만, 재밌는 자리였다.

Tensorflow today and future – Jeff Dean

Jeff Dean 의 발표였다. 주된 내용은 텐서플로우에 대한 소개였다.

자동운전, 번역, 카메라 이펙트 등에 사용되고 있으며, Instachart, Uber, Kewpie등에서 사용되고 있다는 소개로 시작하였고, TPU와 TPU를 클러스터화 시킨 TPU Pod 에 대한 내용이 이어졌다.

Python에서는 주로 high-level의 API가 제공되고 있으며, 모바일에 최적화된 TF Lite, 더욱 간단하게 사용할 수 있는 TF Eager Execution이 소개되었다.

앞으로는 헬스케어, 로보틱스, Connectomics(High-resolution brain imaging) 등의 분야에서 정확도를 높이는데 사용될것으로 전망/기대하였다.

ML in the future

ML(머신러닝)의 현재는 다음과 같다.

  • Solution = ML expertise + data + computation
  • 지금의 머신러닝은 전문가가 아니면 사용하기 쉽지 않은데, 머신러닝에 필요한 계산을 더욱더 간단하게 하고자 한다.

이같은 현재의 상태를 다음의 상태로 바꾸고자 하는 것이 목표.

  • Solution = data + 100X computation
  • 더더욱 머신러닝을 적용하기 쉽게하고, 더더욱 많은 계산량을 처리하고자 하는 것이 구글의 목표다.

Model generating model – 인간이 모델을 만드는 것이 아닌, 기계가 모델을 만드는 AutoML에 대한 소개가 이어졌다.

Per-example routing – 모델을 여러개 생성하여, 각 인풋에 맞는 모델을 적용하는 프레임워크.

구글이(혹은 Tensorflow가) 향후 추구하는 프레임워크 – 다음 세가지를 만족하는 프레임워크를 만들고자 한다.

  • Large Model
  • Sparsely activated single model.
    • 큰 모델 속에 여러개의 작은 모델을 생성.
  • solve many tasks dynamically learn agrow pathways
    • 위에서 설명된 routing에 해당하는 이야기.

다음과 같은 그림을 이용하여 설명하였다.

KakaoTalk_2017-11-29-17-22-00_Photo_20

 

TFUG(TensorFlow User Group Tokyo) Community Session

https://tfug-tokyo.connpass.com/ 에 대한 소개.

가서 보는게 빠를듯하나 일본어 자료가 다수인듯하다.

Fierside Chat (Q&A Session)

Jeff dean 에게 질문하는 코너. 질문은 사전에 받은 내용 위주에 TFUG의 몇 명의 엔지니어가 좌담회 비슷하게 진행하는 식이었으나, 거의 Jeff dean의 답변위주로 진행되었다.

  • Google Brain에 조인하게 된 계기는?
    • 90년대부터 RNN등에 관심을 갖고는 있었으나, 그때는 인프라가 부족해서 관심을 미뤄두고 있었다. 그러나 현재는 인프라와 분산처리기술이 발달하여 충분히 실현할 수 있는 상태가 되었고, 관심을 갖고 있던 것들을 할 수 있는 기회라 생각하여 조인하였다. 구글 브레인은 실생활에 관련된 문제를 해결하기 때문에 더더욱 재밌다. 나는 비록 머신러닝 연구자(Machine learning people)는 아니지만, 대규모 시스템을 구축하며 머신러닝 연구자들과 함께 일하는 것은 즐거운 일이다.
  • TF에서는 최적화 알고리즘(Optimizer)으로 분산처리에 최적화 되어있다고 보기는 힘든 SGD(Stochastic gradient descent)이 사용되고 있다. 혹시, 가까운 시일내에 분산처리에 더욱 최적화된 최적화 알고리즘을 기대할 수 있는가?
    • 최적화 알고리즘을 연구하는 일은 재밌는 일이다. 그러나 현재로서 그 부분에 대한 계획은 없다. 아직은 Batch의 스케일링쪽으로 신경을 쓰고자 한다.
  • Distributed Learning에서는 Parameter server를 업데이트하는 부분이 버틀넥이 될 것 같은데, 어떻게 해결하고자 하는가? 동기(Synchronize)와 비동기(Asynchronize) 방식중 어떤 방식으로 하고 있는가?
    • 적절한 Sharding과 Replication으로 해결하고 있다. 예전에는 Synchronize방식에서 버틀넥이 심했다. CPU시절에는 Asynchronize식으로 했는데, TPU이후로는 Synchronize방식으로 parameter를 관리하고 있다.
    • 이 부분을 내가 제대로 이해했는지 좀 의심스럽다. ㅜ

 

[Perl] autovivification

perl에서는 autovivification 이라는 강력하고 어찌보면 생소할 수 있는 기능이 있다.

 

autovivification 이란?

깊은 깊이를 갖는 자료구조에서(deep data structure), 선언과 초기화에 필요한 장황한 코드를 사용하지 않고도 초기화를 진행해 주는 기능이다.

다음 예제를 통해 살펴보자.

use Data::Dumper;

my $fruit_count = {};

print "Before: \n";
print Dumper $fruit_count;

$fruit_count->{apple}++;
$fruit_count->{orange}++;

print "After: \n";
print Dumper $fruit_count;

위 예제의 실행 결과는 다음과 같다.

ahn-soohan@Mac-261:fout/perl_practice $ perl autovivification1.pl 

Before: 
$VAR1 = {};
After: 
$VAR1 = {
          'orange' => 1,
          'apple' => 1
        };

선언하지 않은 orange와apple에 대해서 카운터가 1씩 올라가 있는 것을 볼 수 있다.

이처럼 autovivification 은 잘 활용하면 편한 기능일 수도 있겠지만, 의도치 않은 결과를 나타내면서 악마와 같은 기능을 할 수 있는 양날의 검이다.

다음의 예제를 한 번 살펴보자.

use Data::Dumper;

my $members = {};

print "Before: \n";
print Dumper $members;

print "It exists.\n" if exists $members->{ahn}->{items};

print "After: \n";
print Dumper $members;

결과는 다음과 같다.

ahn-soohan@Mac-261:fout/perl_practice $ perl autovivification.pl

Before: 
$VAR1 = {};
After: 
$VAR1 = {
          'ahn' => {}
        };

위의 소스 코드에서는  ahn이라는 필드를 선언한 적이 없는데도 불구하고, 비교에 쓰였다는 이유만으로 해쉬에 ahn이라는 필드가 생성되어있다. 이 기능의 강력함을 좀 더 잘 살펴보기 위해 더욱 deep한 필드에 대한 실험을 해보면,

use Data::Dumper;

my $members = {};

print "Before: \n";
print Dumper $members;

print "fruit exists.\n" if exists $members->{ahn}->{items}->{fruit};
print "vegetable exists.\n" if exists $members->{ahn}->{items}->{vegetable};

print "apple exists.\n" if exists $members->{ahn}->{items}->{fruit}->{apple};
print "potato exists.\n" if exists $members->{ahn}->{items}->{vegetable}->{potato};

print "after: \n";
print Dumper $members;

print "fruit exists.\n" if exists $members->{ahn}->{items}->{fruit};
print "vegetable exists.\n" if exists $members->{ahn}->{items}->{vegetable};

결과는 다음과 같다.

ahn-soohan@Mac-261:fout/perl_practice $ perl autovivification.pl

Before: 
$VAR1 = {};
after: 
$VAR1 = {
          'ahn' => {
                     'items' => {
                                  'fruit' => {},
                                  'vegetable' => {}
                                }
                   }
        };
apple exists.
potato exists.

없던 ahn뿐만 아니라, 하위 필드인 items와 그 밑에 fruit와vegetable 까지 생성된 것을 볼 수 있다. 게다가, 처음 if문에서는 exists에 걸리지 않았던 조건문이 autovivification후에는 exists에 걸려서 코드의 동작이 달라진 것을 볼 수 있다. 이런 경우는 보통은 개발자가 의도하지 않은 경우가 많으므로, 이런 부분에 대해서 주의를 할 필요가 있다.

autovivification을 사용하지 않도록 하기 위하여

아래 코드 한줄을 추가해주면 autovivification이 일어나지 않도록 할 수 있다.

no autovivification;

위 예제에 이 코드를 추가하여 실행하여 보면 아래와 같은 결과를 얻을 수 있다.

  • 코드:
    use Data::Dumper;
    
    no autovivification; # here!
    
    my $members = {};
    
    print "Before: \n";
    print Dumper $members;
    
    print "apple exists.\n" if exists $members->{ahn}->{items}->{fruit};
    print "potato exists.\n" if exists $members->{ahn}->{items}->{vegetable};
    
    print "apple exists.\n" if exists $members->{ahn}->{items}->{fruit}->{apple};
    print "potato exists.\n" if exists $members->{ahn}->{items}->{vegetable}->{potato};
    
    print "after: \n";
    print Dumper $members;
    
    print "apple exists.\n" if exists $members->{ahn}->{items}->{fruit};
    print "potato exists.\n" if exists $members->{ahn}->{items}->{vegetable};
  • 결과:
    ahn-soohan@Mac-261:fout/perl_practice $ perl autovivification.pl 
    
    Before: 
    $VAR1 = {};
    after: 
    $VAR1 = {};

nginx conf에서 location 설정

nginx conf에서 location 설정

  • location = [PATH] (Exact matching)

[PATH]에 해당하는 경로만 적용. location이 이 경로와 매치가 되면 곧바로 검색을 중단하고 이 이하의 설정을 적용한다. 다른 경로 검색을 줄일 수 있기에 조금은 더 빨리 처리할 수 있다.

  • location [PATH] (Prefix matching)

[PATH]로 시작하는 경로들에 적용. 하지만 다른 경로를 검색하여 regex 매치가 발생하는 경로가 있다면 그 경로의 설정을 우선적으로 적용한다.

  • location ~ [PATH regex] (Regular express matching)

[PATH regex]의 규칙에 해당하는 경로들에 적용.

  • location ^~ [PATH regex] (Regular express matching)

[PATH regex]로 시작하고 regex 에 걸리는 경로들에 적용. 이 규칙에 해당되면 바로 탐색을 중단한다.

  • location ~* [PATH regex] (Regular express matching)

location이 [regex] 로 끝나는 것들에 적용. 다만 ^~가 더 높은 우선순위를 가진다.

우선선위 정리

  • Exact matching
  • Regular express matching

  • Prefix matching

 

제6차 Kodeveloper 고군분투기

jsoup을 이용한 파일 다운로드 (@msna)

지난 시간서 이어서 자동 동영상 다운로드에 대한 발표를 진행하셨다.
RSS피드를 이용한 자동 다운로드를 Transmission + FLEXGET를 통해 진행하셨고,
jsoup을 이용한 크롤링에 대해서 발표하셨다. 이 과정에서는 우선 사이트의 구조를 확인하고 크롤링을 하였고, 큰 구조를 확인한 뒤 세부구조를 확인하여,
대상을 타겟팅하여 크롤링을 진행하셨다.
몇 단계의 실패가 있었는데, 첫번째는 User Agent를 설정하지 않았던 부분, 그 다음은 본문화면에 대한 쿠키 설정의 누락, 그리고 마지막은 컨텐츠타입에 대한 설정 에러였다.
이것들을 해결하고 무사히 크롤링을 마칠 수 있었다고 한다.

그러나 결론은.. 위의 기능을 제공하는 기존 라이브러리가 있었기에, 그냥 기존의 라이브러리를 이용하자. 로 이어졌다.

키보드 (@fish)

각 종 키보드 종류에 대한 발표와, 키보드가 돌아가는 간단한 원리 그리고 소재 등에 대한 발표였다.

키보드 종류:

  • Rubber dome
    제일 흔하고 싼 키보드로 보통 회사에서 지급하는 키보드들이다. 노트북들도 대부분 이 종류다.
    키감은 그렇게 뛰어나지 않다. 보통은 키캡 밑에 플라스탁이 X자로 교차되면서 그 가운데 고무(안에 있는 스프링)을 누르는 방식으로 작동이 된다.
    최근 맥북은 이것이 X자가 아니라 V자로 교차되는 방식이라 키감에 불만을 표하는 유저도 상당수 있다고 한다.
    X자 형태로 제작하면 라이센스비가 들어서 이 부분의 지출을 줄이고자 하는 것이 이렇게 만든 이유라고 한다.
  • 기계식 스위치 (mechanical switch)
    금속끼리 부딪혀서 작동하는 원리의 키보드. 몇 가지 스위치 방식이 있는데 체리 스위치가 제일 많이 사용된다고 한다.
    한국 개발팀서는 이 방식의 키보드를 많이 사용하지만 일본에서는 그렇게 눈에 띄지 않는다고 한다.

키캡(keycaps)

  • ABS: 제일 흔한 플라스틱 저가형 소재. 시간 지나면 누래지는 키보드들이 이 키캡이다. 방염방지 약품이 자외선 쐬면 나타나는 현상이라고 한다.
  • PVS: ABS와 비슷한 흔한 저가형 소재.
  • PBT: 좋은소재. 다만 가격이 위 소재들의 1.5~2배라고 한다.
  • POM: 체리에서 쓰이는듯?

사이즈

  • 풀: 비개발자들이 가장 많이 사용하는 오른쪽에 숫자판까지 다 달려있는 흔한 키보드.
  • tenkeyless : 오른쪽 숫자판이 없는 형태의 키보드.
  • ISO VS ANSI: ISO는 엔터가 ㄱ자, ANSI는 일자
  • 그외에 75% 60% qwerty 사이즈가 있다고 한다.

DIY

키보드 DIY를 위해서 가장 필요한 부분은 인내, 용기, 돈, 돈, 그리고 돈! 이라고 한다.
3D 프린터로 키보드 튜닝은 추천하지 않으셨는데 이유로는 키캡이 거칠고 3D 프린터로 뽑기에는 크기가 너무 크다는 것이었다..
흔히 하는 방식중 하나로는 레이저커터로 아크릴잘라서 쌓는식이라고 한다.
부품은 cherry MX가 alps보다 구하기가 좀 더 쉽다고 한다.
키보드 펌웨어는 새로 짜기에는 재미없고 단순작업이라 그리 보람있는 일은 아니기에 그냥 기존에 있는거 쓰는게 낫다고 하신다.

Bingo

Azure를 이용하여, 그 중에서도 메시지 Queue를 이용하여 빙고게임을 구현하고자 하셨지만,
구현이 미완성이었다.

Incidents Management

라쿠텐에서의 장애 대응에 대한 간단한 발표를 하셨다. 언급해도 되는 부분인지 모르겠지만..
오류가 오면 오류알림이 Bot으로 도달하면 자동으로 티켓이 업데이트가 되고, 개발자는 그 티켓을 보고 대응한뒤 Bot에 상태를 업데이트하여 통지를 하면,
티켓이 자동으로 업데이트가 되는 식으로 작동한다고 한다.

2016년 그리고 2017년

2016년의 막이 내리고 2017년이 밝았다.
2017년부터는 주1회씩 블로그 포스팅을 하고자 한다. 일일커밋과 비슷한 느낌으로 개발 관련 포스팅을 하고자 한다. 아주 조금이지만 읽어주는 사람이 있고, 설사 읽어주는 이 없더라도 내 개인적인 개발에도 도움이 되리라 믿기 때문에 다른 것보다도 블로그 포스팅을 열심히 해보고자 한다.

2016년 회사일

FreakOut에 입사한지 일년이 조금 더 지났다.

아직도 광고에 관해서 모르는 것이 많고 많이 배워나가는 단계다.

~ 6월: LINE Ad Platform

상반기에는 우리 FreakOut의 자회사 MTBurn에 파견되어 LINE에 광고를 배포하기 위한 플랫폼 개발에 시간을 보냈다. MTBurn에서 개발된 SSP(Supply Side Platform) Hike에 LINE에 필요한 프로토콜을 추가하여 개발하고 이를 위해 Go언어를 배우고 써보는 좋은 기회가 되었다.

애초에 SSP를 개발할때는 OpenRTB에 충실한 프로토콜을 구현하고자 하였으나, LINE에 광고를 내보내게 되면서 변형된 프로토콜을 많이 구현하게 되었다.

FreakOut에서의 업무도 같이 처리하였는데, 우리의 DSP를 Hike와 연결하는 부분을 구현하였다.

~ 10월 Video Ad for LINE

Hike를 통해 LINE Ad Platform과 성공적으로 연결하고, 그 다음 업무는 LINE에 동영상 포멧의 광고를 배포하는 것이었다.

상당히 어려운 부분이 있었는데, 라인의 광고를 사진, 동영상에 상관없이 같은 spot id로 오게 되어 있는데, 사진과 동영상의 광고가격 책정이 다르기 때문에, 내부 경매를 할 시에 참조해야되는 인덱스를 따로 써야되는 문제가 있었다.

이는 인덱스를 두 번 읽어야하기 때문에 시간적으로 퍼포먼스가 상당히 안좋아지는 문제가 생겼다. 이 부분의 해결을 위해서 단순히 연결하는 부분 이외에 우리의 DSP가 갖고 있던 여러가지 문제점들을 최적화하는데 많은 시간을 할애하였다.

다행히 시간을 줄이는데 성공하였고, 완전 만족스럽지는 않지만 실제로 배포를 하기에는 문제가 없는 수준까지는 만들었다. 앞으로 이 부분은 인프라 증설로 해결하지 않을까 생각된다.

~ 12월 Demographic targeting

LINE에 광고를 배포하게 되면서, LINE의 Demographic 정보(연령대, 성별)를 로그에 축적할수 있게 되었다. 이를 LINE면뿐만 아니라 다른 면에도 활용해보기 위한 프로젝트가 다음 업무였다.

우리 회사의 DMP에 audience_id를 기반으로 설정해놓은 segment로 Demographic정보를 추측하는 것이 주요 내용이었다. 단순히 Naive bayes를 사용하여 예측해봤는데 생각보다는 나쁘지 않았다. 예측 결과를 성별과 연령대를 따로 내는 것보다 [성별-연령대]를 묶어서 예측하는 것이 결과가 더 좋았다.

그리 복잡하고 어려운 프로젝트는 아니었지만, 그래도 하둡쪽의 소스코드도 많이 보게 되고, 회사에 들어와서 간단하지만 처음으로 해본 머신러닝 관련 프로젝트여서 상당히 뿌듯하게 한 프로젝트다.

업부면에서 느낀점

손으로 움직이기 전에 설계와 문서 정리부터..

내가 성격이 상당히 급한 편이라 개발자로서는 치명적인 약점인데, 이것을 여실히 느낀 한 해였다. 가장 많이 느꼈던 점은 코드리뷰를 내고 나서 다른 사람들에 비해서 상당히 많은 코멘트들과 리뷰를 받게 되는데, 한두번이 아니었기 때문에 이에 대해 생각을 해봤다.

나의 역량이 모자란 측면도 있었겠지만, 내가 할 수 있는 우선적인 일은 코딩을 시작하기 전에 설계부분에 좀 더 신경을 쓰고 문서 정리를 확실히 해놓는 습관을 들이는 것이다. 문서 정리는 이번 년도에 가장 신경 쓴 부분이고 매니저도 요구한 부분이었고, 매니저의 평가는 괜찮은 편이었다. 하지만 내 스스로 만족스러운 코드를 작성하기 위해서는 더욱 이부분에 충실해야하고, 더 많은 부분 세세한 부분들에 대해서 생각해야겠다고 느꼈다.

그 외 활동

외부 발표

큰 컨퍼런스는 아니고 매월하는 스터디긴하지만 외부에서 해본 첫 발표라 서툴기는 하고 어찌보면 아무것도 아닐수도 있지만 참 뜻깊게 생각한 발표다.

Cousera – Introduction to Natural Language Processing

스터디 발표를 준비하면서..

한인 개발자들끼리의 스터디가 최근 결정이 되었고 1회 모임을 가졌었으나, 나는 그날 모임에 참석하지 못했다. 1회 발표자였던 김현재군의 지목으로 2회 모임의 발표자를 제의 받았다. 나 역시 마침 지금 회사로 옮긴지 1년이 되어 1년동안 공부하고, 배우고, 일했던 내용을 정리할 좋은 기회라고 생각되어 선뜻 수락하였다. 지금 현재 발표는 무사히 마쳤고, 이번 글에서는 발표를 준비하면서 느낀 점들을 정리해보고자 한다.

 

 스터디는 청취, 청강보다는 발표를!

일하면서 많은 개발자님들의 글들에서도 볼 수 있고, 현 직장의 매니저도 강조하는 부분이다. 나 역시, 석사과정에서 수도없이 느꼈던 부분이고, 이번 발표를 준비하면서도 새삼 느꼈던 부분이다.

발표에서 가장 중요한 부분은 청중들이 알아들을 수 있는가이다.

이를 위해서는 해당 지식에 대해서 머리속에 잘 정리가 되어 있어야 하는 것이 기본이다. 머리속에 있는 지식을 입 밖으로 꺼내어 말로 전하기 위해서는 많은 연습도 필요하지만, 머리속에서 내용이 잘 정리되어 있지 않은 상태에서, 어렴풋이만 알고 있는 상태에서는 버벅대거나 청중들이 알아듣지 못할 말들만 나올 뿐이다. 특히, 단순한 내용 나열만이 아닌 청중들이 알아듣기 쉬운 표현으로 말을 하기 위해서는 발표에 필요한 지식들을 유기적으로 잘 이해하고 정리 할 필요가 있다. 어떤 내용을 어떤 순서로 전할지, 어떤 내용을 꼭 말하고, 어떤 내용을 말하면 이해에 방해가 되기에 생략할지… 모두 내용에 대한 이해가 없이는 불가능한 일이다.

이렇듯 청중들이 알기 쉬운 발표를 위해서는 기존에 알고 있는 내용도 정리하고, 매끄러운 진행을 위해서 여러 자료들을 찾아보고, 이것들을 내용에 넣고 빼는 일을 반복하면서 준비해야 한다. 또한, 예시나 예제까지 직접 준비한다면 내용 이해는 더욱 확실해 질 것이다. 이만한 공부 방법은 없다고 생각한다.

 

자신있게!

물론, 대단한 사람들, 대가들의 발표도 많이 있지만, 그렇지 못한 사람도 자신감을 갖고 과감히 발표자가 되도록 하자. (물론, 나도 아직 부단히 노력해야되는 부분이다.) 청중의 입장이 되어 생각해보면, 스터디에 참석하는 것은 전문적이고 상세한 내용을 알기 위해서도 있겠지만, 그보다는 새로운 내용과 그에 대한 개요(introduction) 및 간단한 팁을 얻고자 하는 목적이 더 크리라고 생각된다. 물론, 전자에 해당하는 스터디도 있으나, 후자의 케이스도 충분이 많았던 것으로 기억된다. 그렇기에 어려운 내용이 아닌, 자신이 알고 있는 지식만 확실하게 잘 정리하여 전달을 하는 것만으로도 그 발표는 충분히 가치가 있다.

나 역시 이 업계에서 대단한 실적을 올린 그런 개발자도 아니고, 경력도 아직 일천한 개발자이다. 그래서 청중들의 귀중한 시간을 망칠 수 없다는 생각에, 내가 할 수 있는 부분만 확실하게, 열심히 준비하였다.

겁 먹지 않고, 저지르고 보는 것이 필요하다. 자신있게!

일본에서 일하면서 듣는 질문들(취업)

일본에서 일하다 보면 많이 듣게되는 질문들이 있는데, 오늘은 이에 대해 포스팅을 써볼까 합니다.

일본에서 일하기 위해서 일본어는 어느정도 해야됩니까?

사실 워낙 case by case라 모든 질문에 대한 답은 이 문구를 앞에 달고 한다는 것을 전제로 하겠습니다. 그리고 소프트웨어 엔지니어로서의 입장을 얘기하는 것 또한 전제해두겠습니다.

일본어를 못해도 일을 할 수 있고 취업을 할 수 있습니다. 실제로 라쿠텐같은 경우는 회사 공용어로 영어를 사용하여 토익 800만 넘으면 지원이 가능하고 실제로 일본에서는 토익 800을 넘는것이 부담스러워 일본인들도 넣는 것을 어려워하는 점도 있습니다. 실제로 외국인의 비율이 점점 늘고 있다는 라쿠텐 출신의 저희 회사 엔지니어도 말하고 있습니다. 라인 같은 경우에도 일본어를 못해도 입사 자체에는 지장이 없는 것으로 알고 있고.. 저희 회사도 실제로 중국인 엔지니어가 일본어를 거의 못하는 상태로 입사하였습니다.

그러나 일본어가 안된다면 취업 자체는 가능할지 모르나, 본인 스스로가 일을 하면서 불편함을 겪게 되는 점이 가장 큰 문제가 될 것이고, 이것이 간혹 퍼포먼스로 이어질 수가 있습니다. 라쿠텐 같은 경우는 영어가 공용어라고는 하나, 일본인과 의사소통할때는 아무래도 영어가 잘 통하지 않는 경우도 있다고 합니다. 저희 회사 같은 경우는 일본어가 안되는 외국인은  영어로 진행해도 별 무리가 없는 포지션에 있는 경우가 대부분이긴 합니다만, 다른 포지션에서는 영어로 커뮤니케이션이 힘든 팀도 분명 있습니다.

그리고 일본어가 전혀 안되는 상황이어도 뛰어난 실력을 입증할 수 있으면 입사에 큰 문제는 없다고 생각됩니다.

특히, 신졸로 신입으로 들어오는 직원의 경우 미친듯이 뛰어난 이력이나 경력이 아니어도, 포텐셜을 보고 채용한 후 일본어 교육을 실시하는 경우도 있으니, 일단 부딪혀보는게 좋지 않을까 생각됩니다.

일본의 현재 취업 상황은 어떤가요?

여러가지가 맞물려 취업 경기가 괜찮은 편입니다. 베이비붐 세대가 은퇴하는 점도 있고, 일본도 한국과 마찬가지로 소프트웨어 엔지니어에 대한 수요가 필요한 상황입니다. 특히, 게임 업계 같은 경우에는 유니티 엔지니어가 상당히 모자란 상태인데, 이는 분명 한국 엔지니어들에게 유리한 상황이라고 생각합니다.

백엔드 엔지니어, 머신러닝 엔지니어들에 대한 수요도 많이 필요로 하는 상황입니다.

초봉 & 연봉상승은 어느정도 되나요?

보통 신졸은 300~350 받는 경우가 많고, 그외에 게임업계 같은 경우가 돈을 더 주는 경우가 많습니다. 그리고 상여는 연2회정도 나오고.. 교통비는 물론 지원됩니다.(안 해주면 일본의 철도값 감당 못합니다.) 그리고 회사에 따라서는 주택수당 혹은 주택보조를 해주는 경우도 있는데, 이 경우에 독신의 경우에는 상당히 도움이 됩니다.

여기에 세금 같은 경우에는 보통 보험+소득세로 15%정도 띄인다고 보면 되고, 주민세는 부양가족이 얼마나 있는지에 따라서 다른데 이는 저도 아직은 정확하지가 않아 나중에 따로 포스팅 올리겠습니다.

연봉상승 같은경우에는 저도 아직 그렇게 사회생활을 길게 한 것이 아니라 잘은 모르겠지만, 오르는 폭이 확 크지는 않은 것으로 알고 있습니다. 최근에는 일본 역시 장기근속이 미덕이던 시대는 지나고, 이직을 통해 몸값을 올리는 케이스가 많은것 같습니다. 적어도 엔지니어에게는..

일본의 업무 환경은 어떤가요?

퇴근 & 야근 & 야근수당

일본도 물론 야근과 퇴근시간에 대한 상사, 팀의 눈치보기가 없는건 아닙니다. 한국의 그런 문화들은 아마도 일본에서 유입되었을 것 같으니.. 다만, 한국에 비해서 체감상은 심하지는 않다고 생각됩니다. 특히, 상사가 퇴근 못한다고 눈치보면서 퇴근 못하는 그런건 거의 없다고 봅니다. 업무자체가 많아서 야근하는건 있지만..

그리고 대부분의 회사에는 월 45시간이 넘어가면 야근수당을 지급하도록 되어있습니다. 야근수당을 지급하지 않는 일본회사는 거의 없고, 있다면 이미 블랙회사로 악명이 자자할 것입니다. 그리고 한 직원이 월 45시간을 넘어가는 것이 일정이상 되면 정부차원에서 경고를 받는것으로 알고 있습니다. 그래서 일본에서도 정직원들의 야근시간에 대하여 신경을 쓰는 편입니다.

여기서 함정은 간혹 저런 현상을 피하기 위해 퇴근계에는 정시퇴근이라고 찍고 야근을 하는 직원도 있긴합니다만.. (제 이전 사수가…) 그건 개인의 성격문제라 봅니다. 저걸 강요하는 회사라면 블랙회사이니, 애초에 잘 알아보고 안갈수 있도록 해야죠.

업무 스타일 & 회식

업무 스타일은 한국보다 업무시간에 좀 더 집중하는 분위기랄까.. 한국에서 일해본 경험은 적지만, 업무시간에 좀 더 우직하게 업무에 집중하는 분위기(혹은 우직하게 업무에 집중하는 척)입니다. 딱히, 티타임 내지 담배타임 등의 시간으로 보내는 시간은 거의 없는 편입니다.

회식 같은 경우에는 간혹 있긴 합니다만, 대부분의 회식은 각자 부담이기 때문에 오라고 딱히 강요하지도 않습니다. 그걸 가지 않는다고 업무나 평가에 반영되는 분위기도 아니고.. 회식문화 안 좋아하는 분들에게는 다른건 몰라도 이 점만큼은 일본이 편하지 않을까 생각됩니다.

한국계..

간혹 비자를 얻기 쉽게 얻기위해, 한국계 인력파견 업체 혹은 한국계 SI업체로 취업을 하여 건너오는 분들이 계신데, 잘 알아보고 오시는 것이 좋다고 생각합니다. 사실, 여러 문화가 공존하는 회사문화는 각 문화의 어떤점들이 융화 되는가가 중요한데, 이런 한국계 등은 한국과 일본의 안 좋은 점들을 섞어놓은 경우가 많은 것으로 알고 있습니다.

물론, 라인같은 좋은 기업도 있지만, 잘 알아보시는게 좋다고 생각합니다. 특히, 취업 계약 과정에서 뭔가 석연찮은 부분이 있으면 취업 후에 블랙일 확률이 높으니 피하시는게 좋다고 봅니다. 예를들면, 취업비자도 안 나왔는데 우선 관광비자로 일하라고 시킨다던가.. 시용기간 중에는 월급은 반토막 내버린다던가.. 그런 경우도 있다고 하니 잘 알아보시길 바랍니다.

일본 취업에 도움이 될만한 사이트 및 에이전트

아래에 생각나는 사이트들을 적고 이번 포스팅은 마치겠습니다. 다른 질문들도 몇 개 더 있는데 그건 다음 포스팅에..

Work in Japan : http://www.workinjapan.co.kr/

Top Career: http://www.topcareer.jp/

Global Touch: http://cafe.daum.net/globaltouch

그 외에 외국계 중심으로 연결시켜주는 Robert Walters(제가 최근 이직에 이용한 에이전트) 등이 있는데, 이런데는 개인적으로 문의를 주시는 것이 좋을 것 같습니다. 상황이 허락한다면 제가 도움을 드릴 수 있을지도 모르겠습니다.

 

 

 

 

 

 

 

 

中途採用、FreakOut Inc.

 이전 회사에 입사한지 1년도 채 되지 않은 10개월차. 과감히 회사를 옮기기로 결정하였다.

지금 회사의 상황이 생각보다 별로 좋지 않고, 좀 더 재미있는 일을 하고 싶었다. 머신러닝과 관련된 분야가 새로운 알고리즘 개발과 같은 내가 추구하는 일과도 좀 더 맞지 않을까하는 생각에 고민을 하던 차에 회사 상황도 그렇게 되어 이직을 결심하였다.

LinkedIn을 통해서 여러 에이전트들이 말을 걸었고, 이직에 관심 없을때는 무시하던 메일들에 답변을 하기 시작하면서 이직활동에 시동을 걸었다. 에이전트와 직접 만나 상담을 하고, 해당 에이전트의 회사의 여러 에이전트로부터 여러 군데 기업을 소개받기 시작하였다. 처음에는 서양계 회사들 중심으로 생각하다가 점점 여러군데 넣기 시작하였다.

그러던 도중 도쿄 한인 미트업에서 FreakOut에 대한 간단한 발표를 들었고, 해결할 재미있는 문제들에 대해 다루는 회사라고 판단되었고, 마침 에이전트의 클라이언트 사에 포함되어 있기도 하여, 에이전트를 통해서 지원하였다.

면접은 대부분 무난한 질문들이었다. 특별히 어려운 질문에 대해 파고들기보다는 여러가지 내가 해왔던 것들에 대한 소개가 대부분이었다. 다만, 가장 큰 문제는 나의 회사 경력이 일천하다는 점이었는데, 새로운 기술에 대한 도전에 대한 부분에 대하여 어필을 하려고 노력하였다. 특히, 빠른 시간에 더 많은 트래픽을 처리해야되는 환경에서 일하고 싶고, 그것이 알고리즘에 대해 주로 연구하고 공부해온 내가 일하기에 적합하다는 점을 어필하였다.

내정을 받기는 하였지만, 내 회사경력이 아직 일천하여 가능성을 보고 내정을 통보하였다는 회사 말에 협상의 여지는 크지 않았고, 백프로 만족할만큼 연봉을 올려받지는 못하였지만, 그래도 금전적으로도 단기적으로나 장기적으로 지금 회사보다 유리하다고 판단하였고, 일에 대한 적성도 맞을것 같아서 현재는 이직 결과에 대해 만족한다.