Wednesday, December 23, 2015

Spring Security 에 관하여




<http auto-config="true" use-expressions="true" create-session="never" entry-point-ref="unauthorizedEntryPoint" >

        <form-login
            username-parameter="user_id"
            password-parameter="password"
            login-processing-url="/signin_proc"
            authentication-success-handler-ref="signinSuccessHandler"
            authentication-failure-handler-ref="signinFailureHandler"
            default-target-url="/mypage"
            always-use-default-target="false"
            />

        <logout
        invalidate-session="true"
        logout-url="/signout" />
        <access-denied-handler ref="accessFailureHandler" />

        <custom-filter ref="authenticationTokenProcessingFilter" before="FORM_LOGIN_FILTER" />
    </http>


auto-config 란 ?
기본적
<http>
    <form-login />
    <http-basic />
    <logout />
</http>

 use-expressions="true" 이 있어야지 isAuthenticated() 이런걸 사용할 수 있음


 create-session="never" 이 있을때 세션을 만들지 않는다네


 entry-point-ref
 모든 URL에 대해 어찌되었든 권한에 맞지 않는 경우 이쪽으로 호출하게 된다.

 isAuthenticated()
 user 아이디와 패스워드 권한이 통과해야함


  <custom-filter ref="authenticationTokenProcessingFilter" before="FORM_LOGIN_FILTER" />

로그인 하기 전에 일로 감

Sunday, December 20, 2015

ThreadLocal

금일 ThreadLocal에 대해서 공부를 했다.

static 으로 선언을 하며 ThreadLocal<?>에 있는 객체를
쓰레드마다 set과 get을 할 수 있다.

신기하게도 자동으로 Thread 의 고유한값에 의해서 데이터들을 불러올수 있으며 ThreadLocal의 객체 끼리 자원공유가 안되며..

음..... 아무튼 신기하다.

ThreadLocal을 아직까지는 쓸 이유가 없다고 생각이 든다.

Thursday, December 17, 2015

API 문서 툴을 만들수 있는 프로젝트를 만들어보자(2) Parameter Check

node express 에서 파라미터를 체크를 안할수가 없는데 어찌 되었든간에

아래와 같은 방식으로 파라미터를 체크하고

parameterChecker.checkJson(req, res, ["project_name", "project_detail", "project_type", "project_open"]);



파라미터 체크는 아래와 같은 로직에 의해서 체크된다.
만약에 필수 파라미터에 파라미터가 들어가지 않게 되는 경우
파라미터 파라미터 error 라는 json 데이터를 리턴하게 되고

서버사이드에서는 에러를 발생하게 됨으로써 그 다음 처리들을 skip 해버리게된다.
이런 방식은 Spring3로 API만들때 쓰던 방식인데 노드 js에서도 적용했다.

var errorMessage   =  require('../constant/ErrorMessage');

var parameterCheck = {
  checkJson : function(req,res,  names){

      var canContinue = true;
      for(var i=0; i<names.length; i++){
          var val = req.query[names[i]];

          if(typeof val == 'undefined' || val == null || val == ''){
              res.json(errorMessage.getJsonErrorData('101'));
              throw new Error("parameterError", "custom");
          }
      }
  }
};

module.exports = parameterCheck;


Wednesday, December 16, 2015

API 문서 툴을 만들수 있는 프로젝트를 만들어보자

오늘 처음 고삐를 당겼다.
영감을 얻은곳은 매번 API문서를 만드는게 너무 귀찮고
문서공유도 잘 안되서 처음 생각했고
Yobi 처럼 openSource 화 되어있으면 많은 사람들이 사용할 수 있겠구나 생각이 들어서
시작하게 되었다.

먼저 프로젝트 조합은 아래와 같이 생각한다
reactjs + polymer + html + nodejs + mongoDB

자 그럼 시작

Thursday, December 10, 2015

Easy binding template using regExp in java

this is what easy way to just data binding with regExpression

my template

java

/**
 * Copyright 2009 by  Corp.,
 * All rights reserved.
 * 
 */
package hanwha.neo.modules.mobileapp.util;
import hanwha.neo.commons.IOUtils;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * @author : ddavid
 * @version $Id: HtmlCovertToString.java,v 1.1.2.1 2015/12/11 15:01:53 Exp $
 */
public class HtmlCovertToString {
    
    
    public static String getConvertedString(String path, HashMap<StringString> map){
        return getChangedStr(getFileString(path), map);
    }
    public static String getFileString(String path) {
        FileInputStream fi = null;
        String str = "";
        try {
            fi = new FileInputStream(path);
            str = IOUtils.getString(fi);            
            System.out.println(str);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            org.apache.commons.io.IOUtils.closeQuietly(fi);
        }
        return str;
    }
    public static String getChangedStr(String str, HashMap<StringString> map) {
        StringBuffer output = new StringBuffer();
        Pattern pattern = Pattern.compile("\\{\\{[a-zA-Z0-0]+\\}\\}",
                Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(str);
        // using Matcher find(), group(), start() and end() methods
        int currentIndex = 0;
        while (matcher.find()) {
            String match = matcher.group();
            match = match.substring(2, match.length() - 2); // remove {{ }}
            output.append(str.substring(currentIndex, matcher.start()));
            if (map.containsKey(match)) {
                output.append(map.get(match));
            } else {
                output.append(matcher.group());
            }
            currentIndex = matcher.end();
            /*
             * System.out.println("Found the text " + matcher.group() +
             * " starting at " + matcher.start() + " index and ending at index "
             * + matcher.end());
             */
        }
        output.append(str.substring(currentIndex, str.length()));
        return output.toString();
    }
}
cs

and html file is

1
2
3
4
5
6
7
8
<html>
    <head></head>
<body>
    <p>    this is very good template  name {{name}} and age {{age}}
    </p>
</body>
</html>
cs

where to call is

1
2
3
4
5
6
HashMap<StringString> map = new HashMap<StringString>();
        
map.put("name""david");
map.put("age""15");
            
body = HtmlCovertToString.getConvertedString("testhtml", map);
cs

this is output
1
2
3
4
5
6
7
<html>
    <head></head>
<body>
    <p>    this is very good template  name david and age 15    
    </p>
</body>
</html>
cs

Friday, November 13, 2015

WEB Browser Image Cache 원리

웹브라우저에서는 어떻게 해야 이미지를 캐쉬할수 있을까???? 

개발을 하다 보면 한번 불러온 이미지를 재 로딩하는데 큰 시간이 안걸린다는 것을 확인할수 있다. 다시 말하면 한번 불러온 이미지들은 Web에서 캐쉬를 쌓고 다시 불러올때 캐쉬에서 이미지를 확인한다.

가정 : 
한 화면에 2x2 의 이미지들이 있는데 next button을 누룰시 새로운 4장의 이미지들이 바뀐다.

이미지 캐쉬를 적용하지 않은 상태
next button -> 다음 이미지 가져오기 -> 이미지 4장 로딩

이미지 캐쉬를 적용한다면
최초 4장 이미지를 불러올때 그다음4장이미지 tag들을 미리 만들어준다.
ionic에서 사용하는 방법은  아래와 같다

Now, imagine if we had an image tag with an ng-src always pointed at the image url for Recommendations.queue[1] (aka the next song in the queue). We can make this image nearly invisible with CSS: 1px tall and 1px wide, with an opacity of 0.01 - yet the browser will still download it and place it in cache. Perfect!


Friday, November 6, 2015

Thursday, October 29, 2015

how to make syntax highlight with javascript

I recently made a source that text javascript convert to color highlited script with html tags

below code is what I did and output
I have to do refactoring it providing multilanguage and modules.

I did it this step

1. split rows
2. parsing comments.
3. parsing String values
4. parsing variables
5. line num


https://github.com/jjhangu/colorbeauti/blob/master/test.html

If you need more detail
reply~

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
    /**
 * 주석은 언제 작업하나?? ㅡ.ㅡ;
 */
(function(){
    var MailResizer = function(){
    }
    MailResizer.prototype.data ={
        isMode : 0// 0 default, 1 cotent resized, 2 only image resized
        isVertical : 1,  // 0 false, 1 true,
        imageObjectList : [] //  isMode가 2인경우에만 사용
    };
    // 텍스트 테스트
    var text = "<span id='hoho'>" + '<span id="haha">' ;
    var arr = [];
    var json = {};
    // 이중 for문 테스트
    for(var i=0; i<arr.length; i++){
        // 로그 테스트
        console.log("haha");
        for(var i in json){
            if(i.key == null){
                return ;
            }else if(i.key == true){
            }else if(i.key == false){
            }  /**  1단 테스트 */
            /* 주주석 */else{
                console.log('주석 테스트');
            }
            /**
             이단 테스트 function hohoho 이거는 2단 주석 테스트 입니다 )()()
             */
        }
    }
    var hello = this.call(data);
    window.MailResizer = MailResizer;
})();

Monday, October 26, 2015

About yobi memory and issue

For a while I had no time to upload blog about my daily life and IT technology.
I think time is so fast anyway
What I want to focus on today is source management like github.
In korea, there is search site like google. The company is called NHN.
People who work in that company made issues and source managing tool.
they opened and uploaded it to github.

https://github.com/naver/yobi this is site.


this is aewsome without one condition. after three day working, it occur memory leak.


so I had to stop and start up it. again and again.

I decided to make cron and register it. do it day by day.

this is my script.

echo $(date +"%m-%d-%Y %r")

echo start yobi

rm /home/yobi/yobi-0.8.2/bin/yobipid.log

ps -ef | grep yobi >> /home/yobi/yobi-0.8.2/bin/yobipid.log

echo '-----------------------'

while read U pid ext
do
echo $U pid is $pid
kill -9 $pid
echo process is killed
done </home/yobi/yobi-0.8.2/bin/yobipid.log

if test -f /home/yobi/yobi-0.8.2/RUNNING_PID
then
echo file is exist
echo remove RUNNING_PID
rm /home/yobi/yobi-0.8.2/RUNNING_PID
echo removed
else
echo file is not exist
fi

echo startup
/home/yobi/yobi-0.8.2/bin/start.sh
echo success

프로젝트를 import 후 class 변경할때 엑세스가 거부되었습니다.

그 폴더를 가서 attrib으로 proejct 파일과 classpath 속성을 변경해준다.

attrib -S -H .project
attrib -S -H .classpath



attrib는 도스, OS/2, 마이크로소프트 윈도의 명령 가운데 하나이다. attrib의 기능은 파일 특성 (읽기 전용/r, 보관/a, 시스템/s, 숨김/h)을 설정하고 제거하는 것이다. 이러한 특성들은 파일을 보호하고 분류할 목적으로 다양한 소프트웨어에 사용된다.[1]

수많은 사용자들은 일반적으로 읽기 전용 특성을 마주치면서 소프트웨어 사용 시 사용자가 파일을 덮어쓰거나 추가하지 못하게 한다. 그러나 사용자에게 확인을 받은 뒤에는 소프트웨어가 이 옵션을 무효화할 수 있다. 보관 특성은 어느 파일을 백업할 필요가 있는지를 알려주기 위해 다양한 백업 및 파일 복사 프로그램에 사용된다.[2] 숨김 특성은 영향을 받는 파일들이 수많은 프로그램들에 보이지 않게 하지만 다양한 소프트웨어, 특히 파일 나열, 표시, 검색을 목적으로 설계된 소프트웨어는 숨김 파일을 보이게 만들 수 있으며 숨김 처리되어 있음을 표시해준다. 시스템 특성은 특정한 운영 체제 파일들을 가리키며 다른 특성들에 비해 대부분의 소프트웨어의 작동에 덜 영향을 미친다.

Friday, October 23, 2015

예광탄

어떠한 프로젝트를 완료하기전에 먼저 예광탄울쏘아서 목표물을 맞춘그. 이말은 상세부분 하나부터 끝까지 개발하는것이 아니라 전체적인 그림을 그리고 나서 고객에 전체적인 그림을 보여줄수도 있고 프레임워크에 하나씩 끼우는 방식이다.

괜찮은 생각인것 같다

Tuesday, October 13, 2015

Thread Safe ArrayList

how to make Thread safe Array List

List<Integer> list = Collections.synchronizedList(new ArrayList<Integer>());

Friday, September 11, 2015

bind, call, apply self-testing

name = "super-man";
var obj = {
  name :"mart-man",

  // general  hello : function(){
    console.log("hello  : " + this.name);
      this.test(function(){
        console.log("hello > callback : " + this.name);
      });
  },

  // bind  hello_bind : function(){
    console.log("hello_bind : " + this.name);
    this.test(function(one, two){
      console.log("hello_bind > callback : " + this.name);
    }.bind(this));
  },

  test : function(callback){
    callback();
  }
}

test = function(){
  console.log("out test");
}

console.log(1, obj.name);
console.log(2, name);
console.log(3);
obj.hello();
console.log(3.5);
var hello_outer = obj.hello;
hello_outer();
console.log(4);
obj.hello_bind();
console.log(5);
obj.hello.call(this);
obj.hello.apply({name:'kings-man', test:function(){console.log("third test")}});
console.log('end');


If you don't understand well why this logs printed.
I suguess this website and http://javascriptissexy.com/javascript-apply-call-and-bind-methods-are-essential-for-javascript-professionals/

study it~!


1 "mart-man"
2 "super-man"
3
hello  : mart-man
hello > callback : super-man
3.5
hello  : super-man
out test
4
hello_bind : mart-man
hello_bind > callback : mart-man
5
hello  : super-man
out test
hello  : kings-man
third test
end




Wednesday, September 9, 2015

project euler 320 problem

https://projecteuler.net/problem=230



1. A
2. B
3. AB
4. BAB
5. ABBAB
6. BABABBAB
.......

At first, I tired to find some repeated pattern.  between A And B.
Maybe I took one hour to find it.
but the result was failed. there is no pattern and had not to think about findind pattern.
Finally I thought this way.

A :
14159265358979323846264338327950288419716939937510
58209749445923078164062862089986280348253421170679

B:
82148086513282306647093844609550582231725359408128
48111745028410270193852110555964462294895493038196


Fibonaci (n) = Fibonaci(n-2) + Fibonaci(n-1);

so make array to put length of F(n);

arr[1] = 100;
arr[2] = 100;
arr[3] = 200;
arr[4] = 300;
arr[5] = 500;

if i want to find 320 I should find from arr[5]
because 500 covered 320 index word.
and find 20 position from arr[4];
arr[4] is made of arr[2] + arr[3]
next find 20 position of arr[2]

if the index of arr[] is 1 or 2, the answer is arr[1 Or to].charIndex(20);

My java code is below.
(Actually It is dirty code, need to be refactored)



import java.math.BigInteger;
import java.util.ArrayList;

/**
 * 처음에는 BB가 중복되서 나오는 숫자의 일정한 패턴이 있는줄 알았다.
 * 알고보니 일정한 패턴은 없네..
 * 
 * 그래서 접근하는 방법은 역 Search 방법이다.
 * @author ddavid
 *
 */
public class number230 {
 
 public static String first ="1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679";
 public static String second ="8214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196";
 
 public static BigInteger total = BigInteger.ZERO;
 
 public static void main(String args[]){

  
  long start= System.currentTimeMillis();
  real();
  
  System.out.println(System.currentTimeMillis()-start);
  
 }
 
 public static void DAB(long num){
  String subFirst = "";
  String subSecond = "";
  subFirst = first;
  subSecond = second;
  long val =  num;
  System.out.println("val : " + val);
  
  
  for (int k = 0; k <15; k++) {
  
   String temp =subFirst+subSecond;
   
   subFirst = subSecond;
   subSecond = temp;
   
   if(subSecond.length() > val){
    System.out.println(subSecond.charAt((int)val-1));
    break;
   }
  }
 }
 
 public static void realDAB(long num){
  long val =  num;  // 81420679895522450
//  long val =  35;  // 81420679895522450
  
  System.out.println("val  : " + val);
  ArrayList<Long> cntList  = new ArrayList<Long>();
  cntList.add((long)first.length());
  cntList.add((long)first.length());
  while (true) {
   long two = cntList.get(cntList.size()-1);
   long one = cntList.get(cntList.size()-2);
   
   long sum = one+two;
   cntList.add(sum);
   if(sum > val){
    break;
   }
  }
  find(cntList.size()-1, val, cntList, 0);
 }
 
 public static void real(){
  for (int i = 0; i < 18; i++) {
   long val =  (long)(127+19*i)* (long)Math.pow(7, i);  // 81420679895522450
//   long val =  35;  // 81420679895522450
   
   System.out.println("val  : " + val);
   ArrayList<Long> cntList  = new ArrayList<Long>();
   cntList.add((long)first.length());
   cntList.add((long)first.length());
   while (true) {
    long two = cntList.get(cntList.size()-1);
    long one = cntList.get(cntList.size()-2);
    
    long sum = one+two;
    cntList.add(sum);
    if(sum > val){
     break;
    }
   }
   find(cntList.size()-1, val, cntList, i);
  }
  System.out.println(total.toString());
 }
 
 public static void find(int index, long position, ArrayList<Long> cntList, int i){
  if(index == 1 || index ==0){
   System.out.println("index : " + index + "  position : " + position );
   
   if(index == 0){
    System.out.println(first.charAt((int)position -1));
    total= total .add(BigInteger.valueOf((long)Math.pow(10, i)).multiply(BigInteger.valueOf(Long.valueOf(first.charAt((int)position -1) +""))) );
   }else{
    System.out.println(Long.valueOf(second.charAt((int)position -1) +""));
    total= total .add(BigInteger.valueOf((long)Math.pow(10, i)).multiply(BigInteger.valueOf(Long.valueOf(second.charAt((int)position -1) +""))) );
   }
   return;
  }
  if(position <= cntList.get(index -2)){   // one 위치인경우 
   find(index-2,  position  , cntList, i);
  }else{ // last 위치인경우
   find(index-1, position - cntList.get(index -2), cntList, i);
  }
 }
}

Nodejs Mapper + transaction Opensource 진행과정3

github에서 opensource 를 작업한다고 시작한지 꽤 시간이 지난것 같다.

어쩌다 보니 최초 계획한대로 정리가 된것 같은데.. 오늘은 
query 부분에  Array 가 동적 바인딩이 되도록 진행했다.

처음 코딩을할때 널체크만 생각하고 query 조건들을 파싱하는구조로 잡았었는데
생각이 짧았었다 확장에서 있어 정말 유지보수가 힘든 구조였다.

재귀 방법으로 지금 다시 고민을 하고 있다.


앞으로 해야하는 작업이 조금더 더 깔끔하게 Queue들을 날릴수 없나에 대해 고민해보고
js 테스트 도구 등을 사용해서 단위 테스를 진행하도록 해야겠다.

그리고, 재귀 호출을 통해서 depth의 depth도 체크하는 구조를 만들어야 겠다.

지금 라이브러리로 사이트를 운영중이라서 사용해서는 안된 말은 아니다.
음..


Monday, August 31, 2015

why my commit is not showing up on github

I registered in github and push my code to github but contribution show me that nothing is committed.

main reason is because of your email is not registered in git on local pc

I just follow this step.

Tuesday, August 25, 2015

Nodejs Mapper + transaction Opensource 진행과정2

지금까지 작업해온 부분이고



부족하지만 처음 opensource를 개발하고있으니 진행과정을 꾸준히 올려봐야겠다.

이전까지 진행사항중 할 수 없었던 것.

만약에 user 테이블에 Query를 날린후에 사용자 이름을 특정 테이블에 넣으려면
insert문이 추가되어야 하는데 특정 쿼리를 날린후에 실행되는 코드이기때문에 이경우 어떻게 해결할지 고민하다 callback으로 result값을 받게 만들었다 

예제 Query는 아래와 같다



router.get('/query/test4', function(req, res, next) {
    var tasks = taskM.makeTasks();
    var field = {
        'content': 'yaho'
    };

    tasks.push(taskM.getTask('test.insert_tb_board', field, function(result) {}));
    tasks.push(taskM.getTask('test.insert_tb_board_reply', field, function(result) {
        console.log('lastInsertId : ' + result.insertId);
        for (var i = 0; i < 4; i++) {
            //tasks.push(taskM.getTask('test.insert_tb_board', field));  // tasks의 마지막에 쿼리를 추가
            tasks.unshift(taskM.getTask('test.insert_tb_board', field)); // tasks의 처음에 쿼리를 추가
        }
    }));
    tasks.push(taskM.getTask('test.select_tb_board_reply', field, function(result) {}));

    executeManager.start(res, tasks, false);
});

test.insert_tb_board_reply 를 날린후에 그 결과를 받아서
아래 tasks.unshift 하면서 test.select_tb_board_reply 를 실행하기전 insert_tb_board query를 4번 더 실행하는 코드이다

만약에 test.insert_tb_board 가 실행된후 select_tb_board_reply 가 실행되고 그다음에 4번의 insert가 이루어지고 자 한다면 tasks.push를 호출하면 된다.

framework를 만든 목적이 최대한 코드는 심플하게하기 위해 만들었는데
조금더 두고봐야겠다..

그리고 에러가 났을때는 어떻게 할지 ... 조금더 고민해봐야겠다..

Nodejs Mapper + transaction 진행과정

nodejs에 있는 기본 모듈로 restful api 를 만들기에는 먼가가 밋밋하다

그래서 2015년 6월 23일정도에 mybatis같은 mapper를 만들자고 네이버의 한 카페 스터디 모임을 만들었다.
그리고 오늘 8월 25일..

어느정도 만들어졌다.
물론 테스트도 많이 해봐야하고
사용자들이 많이 사용할지는 두고 봐야하겠지만

여기까지 온것만으로도 나름 벅차오른다.

스터디 모집시 원문
스터디 목적 
1. git 사용방법 및 opensource 커밋터 되보기. (cvs, svn만 사용해보고 아직 git은 사용안해봤네요._)

2. 기본 mysql 모듈을 이용해서 transaction 도 되고 Mapper 도 되는 라이브러리 구현하기.
 - 개발자 관점에서 가장 쉽게 사용할 수 있도록 하는게 1차목표입니다.
 - transaction 원리 공부 - 이부분은 실제로 공부하면서 
 - connection pool  원리 공부 - 이부분은 직접 구현할 예정
 - nodejs mysql connection 기본 insert, delete, update, create 등 sample 구현 및 앞으로의 방향 BrainStorming
 - mybatis 를 모태로 Mapper 를 구현할 예정이긴 한데.. 의견을 나눠서 새로운 패턴을 만들어도 좋음
 - 자료구조로 최대한 효율적인 방법 직접 구현.

3. 검증 
  - pool 이 정상적으로 동작하는지,
  - 동시 접속일경우 지연현상은 어떻게 되는지 및 어떻게 해결하는지의 관점에서 검증 (apache ab or jmeter or 등등등으로..)
  - nodejs 로 db연동하는 개발자의 관점에서 얼마나 사용하기 쉬운지 검증.. (아무리 알고리즘이 잘짜여져있고 속도가 빠르고 좋아도 API 가 복잡하면 일단 사용하기 어렵고 사용하기 거부감을 느끼니..)

4. npm 등록 -> 아직 어떻게 하는지 모름..


지금까지 작업해온 부분이고
https://github.com/jjhangu/mysql-mapper

대략적인 부분은


이렇고.. 그리고 어느정도 잘 다듬고 수정해서
node npm 에도 등록할 수 있으면 해야겠다.



Sunday, August 23, 2015

nodejs time check util

easy way to check time from start to finish

console.time('1');
for(var i=0; i<5; i++){

}
console.timeEnd('1');

1: 0ms

Tuesday, August 18, 2015

개발 경력 5년차

내가 개발자로 들어선지 5년이 되는 해다.
사실 개발자로 들어서고 공부를 하던 안하던 시간은 흐른다고 생각한다.
공부를 한 5년개발자와 하지 않고 시간만 보낸 5년개발자는 약간은 다르지 않을까 생각한다.


처음에는 3-4개월 학원에서 java를 배웠는데 안드로이드 어플을 몇개 출시를 하고선 창업을 생각했었다.. 지금 생각하면 터무니도 없는 실력으로 배짱만 컸던것 같다.

그렇게 나는 회사에 입사를 하게되었고 1년만에 이직을 하려고 마음 먹었던대로 하지 않고 지금 5년동안 꾸준히 다니고 있다.
첫해에는 안드로이드를 개발했다. 안드로이드를 내가 하고자하는대로 UI를 적용할 수 있었고 생각보다 흥미를 느꼈던것 같다.. 그리고 갑자기 Server를 해야겠다는 팀장님의 말을 듣고 Server Side로 발을 담그게 되었는데 그때 발을 담근것이 지금까지 왔다고 볼수 있다.

코딩은 머리보다는 손으로 감각을 익혀야한다고 제일 처음에 배울때 배웠는데 틀린말은 아닌것 같다. 어느정도 익숙해져야지 코딩을 하는데 막힘없이 하는것 같으니깐..

하나를 꾸준히 해야하는데 꾸준히 못하는것 같다.. 개발자라서 그런지 해야하는것도 많고 그렇다. full stack이라는 말이 괜히 나오는게 아닌것 같다. 서버도 해야할줄 알고 구성, DB설계, client 까지 할 수 있는 사람을 full stack 개발자라고 하는데.. 나도 그런사람이 되기 위해서 어쩌면 노력하는지도 모른다.

메인 언어
Java

할수 있는 언어
javascript, c, python 음.. 별로 없네??

사용하고 설계해본 DB
oracle, mysql, mssql, cassandra, redis

사용할 수 있는 서버 컨테이너
tomcat, weblogic 조금

서버 환경
spring3, ibatis, hibernate, nodejs

javascript 라이브러리
angularjs, jquery, 음.....

또.. 또.. 
client 
Android
.....

조금 발을 담가본것
lucene.

최근 흥미로웠던거
projecteuler, topcoder, algorithm 이정도??

opensource부끄럽지만
이제 시작하는거 nodejs-transaction-queue  git허브에서 개발하고 있음..

앞으로 5년은 더 개발할텐데..
집중하고 싶은거

1. 수학
2. 알고리즘
3. 통계 + 하둡관련
4. opensource,
5. DB 설계?

복습도 하나의 공부이니깐..
내가 했던것들을 한번씩 복습을 하는 시간을 가져야겠다
앞으로의 블로그는 새로운것보다는 다시 정리하는 시간으로 가져야겠다

그리고 영어 공부도 다시 시작

힘내라~~~ to myself