반응형

(1) [2006-12-27] 특집5부_ARM과 파워PC에 기반한 임베디드 프로그래밍 최적화 기법
(2) [2006-12-27] 특집4부_성능 이슈 해결을 위한 닷넷 프로그래밍 최적화 기법
(3) [2006-12-27] 특집3부_리팩토링을 이용한 자바 성능 최적화 기법
(4) [2006-12-26] 특집2부_OOP적 개발을 위한 C++ 프로그래밍 최적화 기법
(5) [2006-12-26] 특집1부_개발 환경의 변화와 대응하는 프로그래밍 최적화의 재발견

출처: http://www.dbguide.net/know/know101003.jsp?IDX=1164&K=TITLE&K2=REGID&V=¨?¨????%20?????¡?&catenum=14

분야별 특성에 맞춘 Programming Optimization



프로그래밍 최적화. 코드 몇 줄을 줄이고 실행 속도를 높이기 위해 머리를 쥐어짜던 시절이 있었다. 이미 추억 저편으로 멀어진 그 기억 속에서는 그런 것이 바로 프로그래밍 최적화였다. 그럼 하드웨어의 성능이 예전의 슈퍼컴퓨터와 맞먹을 정도로 높아진 지금, 프로그래밍 최적화가 대체 무슨 의미를 가질 수 있을까? 프로그램의 속도가 조금 빠르거나 느린 정도라면 이제 거의 체감할 수 없는 상황이 되지 않았는가. 성능이 아주 떨어지지만 않는다면 이제 약간의 실행 속도의 차이는 무의미해진 지 오래다. 이처럼 시대가 변했다고는 하지만 분명히 프로그래밍을 위해 갖춰야 할 최적화 항목들은 여전히 존재한다. 코드의 수를 줄이는 것이 아니더라도 OOP적 개발을 위한 기법들이 필요하고, 보다 개선된 프로그램을 위한 리팩토링도 필요하다. 심지어 예전처럼 속도를 따져야 하는 분야도 있다. 바로 임베디드 분야이다. 이번 특집에서는 각 개발 분야에서 중요하게 다뤄져야할 최적화 기법들에 대해 알아본다.


기획·정리
| 정희용 기자 flytgr@imaso.co.kr


리팩토링을 이용한 자바 성능 최적화 기법


허광남 | GS홈쇼핑 EC정보팀 과장


리팩토링, 복잡다단해지는 현대의 소프트웨어 개발에서 이 단어는 점점 중요한 위치를 차지해 가고 있다. 이제 리팩토링은 진정한 개발자의 덕목 중에 하나라고 단언할 수 있을 정도다. 리팩토링을 한다는 것은 개선에 대한 의지가 있음을 뜻하고, 좀 더 나은 코드, 구조, 프로세스를 지향한다는 의미가 된다. 리팩토링으로 소프트웨어의 성능을 직접적으로 높이지는 못 한다. 하지만 코드의 가독성을 증대시켜, 생각하는 프로그래머들의 머릿속 성능을 높여준다. 3부에서는 리팩토링 방법들에 대해 알아본다.


햄버거나 커피 등을 살 때, 또는 백화점이나 편의점에서 물건을 살 때, 우리는 1회용 물건을 쓰는 것에 대한 세금을 낸다. 1회용 물건을 쓰면 환경이 그만큼 빨리 피폐해지기 때문이란다. 그게 사실인지 아닌지 모르겠지만, 내 돈이 나가는 것은 용납이 안 된다. 1회용품의 편리함. 그 반대급부로 만들어지는 쓰레기 처리에 따른 비용을 지불한다고 하는데, 영 맘에 안 든다.

혹시 프로그램을 짤 때도 1회용 프로그램을 짠다는 생각을 해본 적이 있는가? 그런데 우리는 1회용 프로그램을 짜도 세금을 내지 않는다. 다행일까? 1회용 프로그램이 환경 자원을 소모시키지는 않는다. 다만 1회용 프로그램은 쓰레기를 양산한다. 그때 그때 필요한대로 찍어낸 프로그램은 수많은 중복코드를 양산해낸다. 재활용하지 않는 습관 탓에 시스템이라는 환경이 무거워지고 손이 많이 가도록 바뀌는 것이다.

재활용성은 객체지향 프로그램의 핵심원리 중의 하나이다. 재활용성을 높인다는 것은 찍어낼 때 사용하는 템플릿을 얘기하는 것이 아니다. 오히려 업무나 기능을 제어 가능한 곳에 집약시켜서 관리할 수 있도록 시스템 전체의 청결한 상태를 유지하는 것이다. 이리저리 산재된 중복 코드를 정리하는 것이 핵심이다. 이 때 필요한 기술이 리팩토링이다. 이쯤 얘기하면 리팩토링은 정리 정돈에 비견된다. 군대에서 총기수입을 하는 것과도 같고 집에서 설거지를 하는 것과도 같다.




리팩토링이란



Refactoring (Re + Factor + ing) 영어 단어를 요소별로 나눠보면 요소들을 재구성한다는 뉘앙스를 받을 수 있다. 이는 마틴 파울러의 책에서 비롯된 단어인데, 책에 있는 리팩토링의 정의를 보면 다음과 같다.

“리팩토링은 외부 동작을 바꾸지 않으면서 내부 구조를 개선하는 방법으로, 소프트웨어 시스템을 변경하는 프로세스이다.” 마틴 파울러, 리팩토링, P10. 대청출판사 책에 이어서 나오는 내용은 버그가 끼어들지 않도록 주의하면서 코드를 작성한 후에 더 나은 디자인으로 개선하는 방법이라고 한다. 디자인을 먼저 한 후 코드를 만드는 것이 아니라 일단 돌아가는 코드를 작성하고, 그 후에 그 코드가 더 좋은 구성을 갖도록 바꾼다는 것이다. 우리들의 코딩 관행을 돌아보면, 일단 돌아가는 프로그램을 짠다. 그리고? 끝이다. 그 다음으로 넘어간다. 정리? 남은 사람이 알아서 할 것이다. 남은 사람이 자기 밖에 없다면? 날 잡아서 정리하거나, 회사 옮긴다.




리팩토링을 하는 이유



야심찬 초급 개발자가 자주하는 것 중에 하나가 이전 소스에 대한 비평이다. “도대체 어떻게 이렇게 소스를 짤 수 있지. 발로 짜도 이것보다는 낫겠네. 왜 이렇게 if else가 많은 거야. 이 소스 이해할 시간 있으면 차라리 다시 짜고 만다.” 그래서, 다시 짠다. 그리고 오픈하면 이것 저것 버그 리포트와 요구사항이 들어온다. 이것 저것 예외 처리를 해주다 보면 내가 짠 코드지만 보기 싫어진다. 어느 정도 서비스가 안정적으로 돌아가도록 소스를 수정해 놓으니, 이런, 전에 내가 막 뭐라고 했던 이전 개발자의 소스와 별반 차이가 없다.

“제길, 다음 후임이 누가 될지는 몰라도 내 욕 무진장 하겠군.” 문서라도 잘 주면 모르겠지만, 처음 개발할 때 보고했던 문서 그대로다. 요구사항과 수정을 통해서 변경된 내용을 문서에 업데이트하질 못했다. “할 시간이 있어야지.” SM(System Maint enance)분야에서는 거의 이렇게 사는 것이 보통이다.

이전 사람이 만든 소스에서 버릴 것은 거의 없다. 정리가 안 되서 몇 달간 목욕 못한 모습일 뿐이지, 처리할 수 있는 모든 경우의 수는 그 안에 다 가지고 있다. 이런 코드를 새로 짠다는 것은 그 모든 경우의 수를 처음부터 다시 감수하겠다는 의미가 된다.
이전 소스를 씻기고 다듬는 것이 소스 수정을 위한 필수 과정이다. 정리하지 않고 계속해서 소스를 추가해 가는 일은 운동하지 않고 계속해서 먹어대는 것과 같이 시스템을 비만상태로 만들어간다. 움직임이 점차 둔해질 것이다. 정리 안 된 방처럼 발 디딜 팀이 없는 소스가 될 것이다.

무엇인가 소스의 변경이 필요할 때, 기능 추가나 삭제, 수정 작업이 일어날 때 소스의 리팩토링은 포장이사처럼 편하게 작업하도록 도와준다. 리팩토링은 소스의 중복된 부분을 모듈화 시켜준다. 모듈화는 입출력이 명확하기 때문에 이식성을 높여준다. 중복을 제거한다는 것은 시스템의 칼로리를 빼는 것과 같다. 시스템의 복잡도, 즉 코드를 읽는 사람의 머리가 열받는 정도를 낮춰준다. 물론 그렇다 해도 이사 자체는 귀찮은 일이다.




리팩토링을 위한 도구



리팩토링은 그로 인해 영향 받는 프로그램의 수가 적을 대에만 수작업으로 작업해야 한다. 사실 리팩토링을 수작업으로 한다는 것은 추천하지 않는다. 좋은 개발 환경이 있는데 사서 고생할 필요가 없는 탓이다. 리팩토링을 위한 좋은 툴이 많이 나왔다. 일단 통합개발환경(IDE, Integrated Development Environment)을 준비한다. 요즘의 자바 개발 시 많이 사용되는 IDE는 기본적으로 리팩토링을 지원한다.

리팩토링과 함께 진행되어야 할 JUnit 테스트케이스 자동 생성도 같이 지원되고 있다. 리팩토링 작업을 할 경우 여러 줄의 코드들이 수정된다. 이때 영향을 받는 프로그램들을 모두 불러내서 수작업으로 수정할 경우 리팩토링에 대한 공수가 많이 필요한 탓에 감히 리팩토링에 대한 엄두를 낼 수 없다. 하지만 요즘 통합 개발 환경을 지원하는 개발 도구들은 변경 받는 파일들의 목록과 변경 전 후의 코드 비교, 자동 변경 기능을 지원한다. 덕분에 리팩토링에 드는 수고가 전혀 수고로 생각되지 않을 정도다.




리팩토링 진행 방법



리팩토링하는 이유와 리팩토링 도구까지 알아보았으니 이제 리팩토링 방법에 대해 알아볼 차례다. 주저리 주저리 방법들을 늘어놓을 수 도 있겠지만 개발자는 코드로 얘기한다. 바로 이클립스에서 리팩토링을 사용하는 방법을 설명하도록 하자.


<리스트 1> 리팩토링 샘플
1 public void deleteArticle(Connection conn, int seq) throws SQLException {
2 if (conn == null)
3 return;
4
5 // db에서 삭제 - 삭제 테이블로 이동
6 PreparedStatement pstmt = null;
7 pstmt = conn.prepareStatement(QUERY_MOVE);
8 pstmt.setInt(1, seq);
9 pstmt.executeUpdate();
10
11 pstmt.close();
12
13 pstmt = conn.prepareStatement(QUERY_DELETE);
14 pstmt.setInt(1, seq);
15 pstmt.executeUpdate();
16
17 pstmt.close();
18
19 // memo 삭제 생략
20
21 }


리팩토링에 대한 간단한 예를 들기 위해서 <리스트 1>을 보며 설명하겠다. 7~11번 줄의 코드가 13~17번 줄의 코드와 유사한 것을 알 수 있다. 중복이 계속되는 것은 일정한 패턴을 갖고 있는데 중복이 심해지면 패턴 변경에 따른 공수가 많이 필요하므로 소스의 유연성이 떨어지게 된다. 때문에 반복되는 패턴을 메소드화 시켜서 쉽게 코드를 읽을 수 있도록 한다.

<화면 1> 반복되는 부분, 메소드 추출의 대상


<화면 2> 메소드 추출(Extract Method)

이클립스에서 패턴부분을 선택하고, 오른쪽 버튼을 눌러 콘텍스트 메뉴를 열면 중간 위치에 [Refactor…]라는 메뉴가 보인다. 확장 메뉴에서 [Extract Method…]를 선택하면 <화면 2>와 같은 다이얼로그 창이 뜬다. ‘doQuery’라고 메소드명을 입력한 뒤에 파라미터들을 확인한다.

화면 아래쪽의 버튼 중 [Preview]를 클릭하면 <화면 3>과 같이 미리보기 창으로 바뀐다. 이때 화면에 표시되는 정보들이 기가 막힌다. 리팩토링을 통해서 변경되는 소스의 비교와 상단에는 이 리팩토링에 영향을 받는 소스들과 메소드명까지 친절하게 알려준다. 게다가 이클립스가 모두 다 자동으로 바꿔준다.


<화면 3> 리팩토링 결과 미리보기


<화면 4>에서는 다이얼로그에서 만든 doQuery() 메소드의 내용을 볼 수 있다. 소스 비교란의 맨 오른쪽에 있는 네모는 소스 전체에서 변경이 일어난 부분을 표시한 것이다.


<화면 4> 리팩토링으로만들어진 메소드

비교가 끝났다면 [OK] 버튼을 클릭해서 리팩토링을 실행한다. 소스 리팩토링을 마친 뒤에 doQuery() 메소드를 보면, <화면 5>처럼 파라미터가 Connection conn, int seq 두 개임을 알 수 있는데, 여기에 하나가 더 필요하다. 바로 쿼리 부분인데, 이것을 파라미터로 받아야 비로로 doQuery()가 공용으로 쓰일 수 있게 된다.

<화면 5> 리팩토링으로 만들어진 약간 아쉬운 메소드

QUERY_MOVE라는 상수를 파라미터로 대치한다. 이 상수에 마우스 오른쪽 버튼을 클릭한 뒤에 [Refactor]-[Introduce Para meter] 메뉴를 실행시키면 <화면 6>과 같은 다이얼로그 창을 볼 수 있다. 새로운 파라미터 이름을 ‘query’로 정하고 우측의 [up] 버튼을 클릭해서 파라미터의 위치를 조정한다. 파라미터의 변경은 메소드의 모습인 시그니처(signature)를 변경하는 것이다.


마찬가지로 [Preview] 버튼을 클릭하면 <화면 7>과 같이 리팩토링 전후의 소스를 비교할 수 있다.

<그림 7>에서 [OK] 버튼을 클릭해서 만들어진 doQuery() 메소드는 반복되는 쿼리 실행 부분을 메소드 추출(Extract Met hod)과 파라미터로 빼기(Introduce Parameter) 리팩토링을 이용해서 만든 것이다. <리스트 2>는 그것을 이용해서 바뀐 소스의 모습이다.

<그림 7> 파라미터로 만들기 적용하기 전 미리보기


<리스트 2> QUERY_DELETE 부분 리팩토링 과정
1 public void deleteArticle(Connection conn, int seq) throws SQLException {
2 if (conn == null)
3 return;
4
5 // db에서 삭제 - 삭제 테이블로 이동
6 PreparedStatement pstmt;
7 doQuery(conn, QUERY_MOVE, seq);
8 doQuery(conn, QUERY_DELETE, seq);
9
10 pstmt = conn.prepareStatement(QUERY_DELETE);
11 pstmt.setInt(1, seq);
12 pstmt.executeUpdate();
13
14 pstmt.close();
15
16 // memo 삭제 생략
17
18 }

19 private void doQuery(Connection conn, String query, int seq) throws SQLException {
20 PreparedStatement pstmt = null;
21 pstmt = conn.prepareStatement(query);
22 pstmt.setInt(1, seq);
23 pstmt.executeUpdate();
24
25 pstmt.close();
26 }


<리스트 2>는 아직 변경 중인 샘플코드이다. 앞서 만든 doQuery() 메소드를 이용해서 쿼리만 다른 것을 보내면 된다. 필자가 추가한 8번 줄은 10~14번 줄과 동일한 기능을 수행하게 된다. 코드를 정리하면 다음과 같이 된다.


<리스트 3> QUERY_DELETE 부분 리팩토링 후
1 public void deleteArticle(Connection conn, int seq) throws SQLException {
2 if (conn == null)
3 return;
4
5 // db에서 삭제 - 삭제 테이블로 이동
6 doQuery(conn, QUERY_MOVE, seq);
7 doQuery(conn, QUERY_DELETE, seq);
8 // memo 삭제 생략
9
10 }


하단의 구문이 지워지면서 이 deleteArticle() 메소드 내의 PreparedStatement pstmt 선언은 불필요하기 때문에 삭제했다. 처음 보았던 소스에서 많이 정리되었다. 정리를 하고 보니 deleteArticle() 메소드를 호출하는 곳에서 비슷한 기능을 하는 부분을 볼 수 있다.


<리스트 4> 리팩토링 적용 범위 확대
1 // password 확인
2 if (confirmPassword.equals(MASTER_PASSWORD)
3 || confirmPassword.equals(article.getPassword())) {
4 deleteArticle(conn, seq);
5 deleteFiles(conn, seq);
6 } else {
7 resourceName = "/jsp/error.jsp";
8 throw new Exception(CommonUtil.k2a("잘못된 비밀번호"))
9 }

10 public void deleteFiles(Connection conn, int seq) throws SQLException {
11 if (seq == 0){
12 return;
13 }
14
15 // file db에서 삭제 - sts 값 0 로 변경
16 PreparedStatement pstmt = conn.prepareStat ement(QUERY_DEL_SEQ_FILE);
17 pstmt.setInt(1, seq)
18 pstmt.executeUpdate();
19
20 pstmt.close();
21
22 // file 삭제 생략
23 }


<리스트 4>의 16~20번 줄을 보면 앞서 추출한 메소드 doQuery()로 변경할 수 있을 것 같다. 그럼 코드는 <리스트 5>와 같이 수정될 것이다.


<리스트 5> QUERY_DEL_SEQ_FILE 부분 리팩토링 과정

10 public void deleteFiles(Connection conn, int seq) throws SQLException {
11 if (seq == 0){
12 return;
13 }
14
15 // file db에서 삭제 - sts 값 0 로 변경
16 doQuery(conn, QUERY_DEL_SEQ_FILE, seq);
17
18 // file 삭제 생략
19 }


이렇게 정리하고 난 후에 다시 전체적인 코드를 생각해보면 두 개의 메소드가 불필요하다 생각이 든다. 즉 <리스트 6>과 같이 deleteArticles()와 deleteFiles() 메소드를 지우고 바로 doQuery() 를 호출하도록 바꿀 수 있을 것이다. <리스트 6>은 리팩토링을 통해 최종적으로 정리된 소스이다.


<리스트 6> 리팩토링 적용으로 개선된 코드
1 // password 확인
2 if (confirmPassword.equals(MASTER_PASSWORD)
3 || confirmPassword.equals(article.getPassword())) {
4 // db에서 삭제 - 삭제 테이블로 이동
5 doQuery(conn, QUERY_MOVE, seq);
6 doQuery(conn, QUERY_DELETE, seq);
7 // memo 삭제 생략
8 // file db에서 삭제 - sts 값 0 로 변경
9 doQuery(conn, QUERY_DEL_SEQ_FILE, seq);
10 // file 삭제 생략
11 } else {
12 resourceName = "/jsp/error.jsp";
13 throw new Exception(CommonUtil.k2a("잘못된 비밀번호"));
14 }


앞에서 보았던 소스의 if else 구문과 비교해보면 doQuery() 라는 공통으로 사용할 수 있는 메소드와 5줄이 늘어났지만 deleteArticle(), deleteFiles() 두 개의 메소드가 사라졌다. 이전 소스와 비교해보면 메소드 구성은 <화면 8>과 같이 변경되는 것을 알 수 있다.

추가된 메소드는 +화살표, 제거된 메소드는 화살표로 표시되고 변경된 메소드는 그냥 검은 화살표로 표시된다. 화면 아래쪽에 표시되는 소스 비교하는 곳을 보면 더욱 명확하게 알 수 있다.

지금까지 샘플 소스의 구조를 개선하면서 두 가지 리팩토링 기법에 대해 알아보았다. 이 외에도 많은 기법들이 리팩토링 책에 소개되어있고, 이클립스에도 더 많은 리팩토링 기능이 지원된다.


<그림 8> 리팩토링 전 후 메소드 비교



리팩토링 경험담



필자는 이 글을 쓰고 있는 지금 큰 프로젝트를 진행하고 있다. 6년간 하나도 버려지지 않고 운영되면서 그때그때 패치된 페이지를 스프링 프레임워크에 맞춰서 바꾸는 작업이다. 그런데, 작업을 하는 동안 필자가 간과한 것이 있었다. 그렇게 복잡하게 얽히고설킨 페이지를 스프링 프레임워크의 새로운 바닥부터 하나씩 쌓아 올린 것이다. 기존에 운영하고 있는 소스에서 하나씩 뜯어서 새로운 토양으로 옮겨심기를 한 것이다. 이것은 재개발에 가까운 것이었고, 굉장히 많은 시간이 필요했다. 만약 옮겨야 할 소스를 기존의 토양 위에서 조금씩 리팩토링한 후에 옮겼다면 오히려 많은 시간을 절약할 수 있었을 것이다.

실수했다고 생각하는 부분은 다음과 같다. 우선적으로 모든 기능을 다 옮겨올 때까지 신규 페이지는 아직 미완성이다. 하지만 기존의 페이지 내에서 리팩토링을 한다고 하면 이미 모든 기능과 데이터를 다 갖고 있는 상태이다. 다른 파트에서 데이터가 필요하다고 할 때에도 현재 갖고 있는 데이터에서 데이터를 뽑아내서 보다 빨리 전달할 수 있을 것이다.

두 번째로 시간의 압박이다. 기존의 페이지는 언제든지 답이 나온다. 하지만 신규페이지는 모든 테스트를 마칠 때까지 계속 기다리라고 얘기해야만 한다. 바닥부터 모든 것들에 대해서 테스트를 만들어야 하는 탓에 더 많은 테스트 코드들이 필요하다. 여기에도 만만치 않은 시간이 투입된다.

세 번째는 애플리케이션에 대한 자신감이 떨어진다는데 있다. 맥가이버도 아닌데 시간에 쫓기면서 개발할 경우 만들어진 소스는 분명히 수많은 버그를 품고 있을 가능성이 높다. 그 값이 절대 정확하다고 이야기하기 힘들다. 하지만 리팩토링을 통해서 내부로부터 개혁해 나갈 경우 빠진 것 없이 소스를 재구성할 수 있기 때문에 안정된 기반에서 작업할 수 있을 것이다.

전산의 불문율 가운데 유명한 것이 하나 있다. ‘잘 돌아가는 것은 손대지 마라.’ 칼퇴근을 위해서 절대 절명으로 필요한 말이다. 이렇게 관리되는 소프트웨어의 품질은 논하기 힘들다. 그냥 먹고 살기 위한 프로그램과 그것을 관리하는 직장인이 되어버리게 된다. 반면에 리팩토링의 기본 사상은 개선을 위한 노력이다. 막무가내 개선이 아니라 현명한 개선을 위한 방법을 제시하고 있고, 친구격인 테스트 케이스가 그 안전장치가 되어 준다. 한 순간의 품질이 아닌 지속적인 소프트웨어의 건강을 생각한다면 꾸준히 리팩토링으로 손질할 필요가 있다. 그것이 끝없이 변하는 웹 애플리케이션과 같은 소프트웨어일 경우는 더욱 그렇다.
개선을 위한 작은 몸짓에 진정한 프로그래머가 되고 싶은 독자들을 초대한다.


참고 자료
1. 리팩토링, 마틴파울러, 윤성준,조재박 역, 대청, 2002년3월
2. 패턴을 활용한 리팩터링, 죠슈아 케리에브스키, 윤성준,조상민 역, 인사이트,
2006년7월


리팩토링 관련 사이트

1. http://www.refactoring.com/
Refactoring Home Page

2. http://xper.org/wiki/xp/ReFactoring
김창준 님의 Refactoring에 관한 정보

3. http://c2.com/cgi/wiki?CodeSmell
Code Smell

4. http://xper.org/wiki/xp/CodeSmell
Code Smell 번역

5. http://www.okjsp.pe.kr/lecture/ide/eclipse/refactor/eclipse_refactoring.html
Eclipse의 refactoring기능

6. http://www.okjsp.pe.kr/lecture/ide/eclipse/eclipse_install.html
Eclipse 시작하기


 



제공 : DB포탈사이트 DBguide.net

반응형

Jad Decompiler 사용법

Jad home page: http://www.geocities.com/SiliconValley/Bridge/8617/jad.html
Copyright 2000 Pavel Kouznetsov (kpdus@yahoo.com). 


[ 사용방법 ]


1. 클래스 하나만 디컴파일시

           example1.class   를 디컴파일시 

           jad.exe 를 디컴파일할 파일과 동일한 폴더에 놓는다.

         

           Command 창에   jad -o -sjava example1.class   

       

   결과물 : 'example1.java' 

   

2. Package 를 디컴파일시   

         tree  폴더 아래의 모든 클래스파일을 디컴파일시 

         폴더와 같은 폴더에 jad.exe  를 위치하고


          Command 창에    jad -o -r -sjava -dsrc tree/**/*.class 

          

          결과물 : 폴더내에 [src] 폴더가 생성된다. 

=============================================================================================================

윈도우버전(for Windows 9x/NT/2000 on Intel platform)


jad -r -d .\src -s java .\ifxjdbc\**\*.class


참고 : jad -r [-d<directory_for_sources>] [<other_options>] <directory_with_classes>**/*.class



설명 :


-r : 해당 패키지 형태로 디렉토리 구조를 만듬( restore package directory structure)

-d : 디컴파일될 디렉토리(-d <dir> - directory for output files)

 -s java : 디컴파일된 파일의 확장자를 java로 하라


.\ifxjdbc\**\*.class : ifxjdbc 디렉토리 아래의 모든 클래스들 지정



-----------------------------------------------------------------------------------------


이클립스 디컴파일러인 JAD를 설치하는 방법입니다.


이클립스로 개발을하다보면 F3버튼으로 열심히 따라가는 경우가생깁니다.


그러다 라이브러리로 묶여있는 클래스파일들을 로딩하게되면 읽긴읽되 내용을 분석하지못하죠~


그래서 디컴파일러 ~ 컴파일한클래스파일을 다시 자바파일로 보여주는 도구를 설치하게되면


클래스파일도 자바파일처럼 열수있게됩니다^^~



우선 jad.exe, jadclipse_3.1.0.jar를 다운로드 합니다.


jad.exe파일은 이클립스 폴더에 jadclipse_3.1.0.jar파일은 플러그인 폴더에 카피합니다.


window->preference->general->editors->file assosiationsd에서 *.class선택후


하단의 JadClipse Class File Viewr 를 선택후 default 를 선택합니다.


window->preference->java->JadClipse를 선택한후 ignore existing source를 체크해줍니다.


이렇게하시고 이클립스를 실행시키시면 *.class파일을 찾아갈경우 자동으로 디컴파일해줍니다~

http://sourceforge.net/projects/jadclipse



반응형

Mocha - http://www.brouhaha.com/~eric/computers/mocha.html 
Hanpeter van Vliet's first Java Decompiler. Orphaned at Java 1.02, so crashes on inner classes. [Freeware]

WingDis 2.15 - http://www.wingsoft.com/wingdis.shtml 
Command line Java decompiler. [Commercial]

SourceAgain - http://www.ahpah.com/product.html 
Java Decompiler for Win95/NT, Unix, web-based trial version from Ahpah Software. [Commercial]

Jad - http://www.geocities.com/SiliconValley/Bridge/8617/jad.html 
the fast Java decompiler. Separate versions for Win32, OS/2, most Unixen. [Freeware].

SourceTec Java decompiler - http://www.srctec.com/decompiler.htm 
Patch to Mocha which defeats Crema. [Shareware]

NMI's Java Code Viewer - http://njcv.htmlplanet.com 
The "user-friendly, visual" Java decompiler and disassembler for Win32 platform. [Shareware]

Java Code Engineering - http://www.meurrens.org/ip-Links/Java/codeEngineering/ 
Marc Meurrens' page on engineering & reverse engineering Java class files. Review of books and on line resources on: the Java Virtual Marchine (JVM); code engineering & reverse engineering; class browsers, viewers & editors; assemblers; compilers; disassemblers & decompilers; obfuscators & unobfuscators. Comprehensive, well organized site.

Decafe Pro - http://decafe.hypermart.net/ 
Java Decompiler for Win32 platform. [Commercial]

 Kimera - http://kimera.cs.washington.edu/disassembler.html 
Online Java Disassembler. Just enter an URL of a .class file and it will be disassembled into a form suitable for re-assembly by Jasmin. [Freeware] 

Dumping Class Files - http://professionals.com/~cmcmanis/java/dump/index.html 
Chuck McManis's code to parse class files. [Free for non-commercial].

ClassCracker - http://www.pcug.org.au/~mayon/ 
Visual Java decompiler from Mayon Software Research. [Commercial]

Java Optimize and Decompile Environment (JODE) - http://jode.sourceforge.net/ 
Java decompiler with full source code. Supports inner/anonymous classes. Also contains a small, but extensible bytecode obfuscator/optimizer. [Open Source, GPL]

CafeBabe - http://jfa.javalobby.org/projects/CafeBabe.html 
Graphical disassembler and editor of Java bytecodes. Part of the JFA. [Open Source]

RIIS: Decompiling Java - http://www.riis.com/depile.html 
Godfrey Nolan's book on writing your own Java decompiler may never be published, so early chapters are online in PDF format.

dis - http://www.cs.princeton.edu/~benjasik/dis/index.html 
A functional, fast and simple disassembler that is written in C. Like javap, produces bytecode. Download Solaris, Win95/NT versions. Mac or other Unixen or source code by email request. [Freeware]

BackToJava (BTJ) - http://www.backtojava.org/ 
General tool for manipulation of Java bytecode (disassembly, assembly, statistics, decompilation, debug information...), written in Java. In progress. [Open Source, LPGL]

JReveal.Org - http://www.jreveal.org 
Online decompiler and obfuscator. Also has a resource directory. [Freeware]

IceBreaker - http://www.suddendischarge.com/cgi-bin/antileech.cgi?icebreak10.zip 
(Zip-file) A 'Visual' Java decompiler/disassembler. Allows side-by-side comparison of disassembled byte code from class files, for easier decompilation. "Replete with bugs" and dependent on command-line decompiler, such as Mocha or Javap. [Freeware] 

반응형
세계는 나의 한계이며, 나의 한계는 언어의 한계이다.”     - 비트겐슈타인

최근 그 어느 때보다도 다양한 언어에 대한 관심이 높아지고 있습니다. 자바는 JRuby, 그루비(Groovy), 스칼라(Scala) 등을 통해 언어를 넘어 플랫폼으로 발전하고 있고, 닷넷은 CLR(Common Language Runtime), DLR(Dynamic Language Runtime)을 통해 다양한 언어를 지원하고 있습니다. 또한 동적 언어와 함수형 언어에 대한 관심도 뜨겁습니다.

이번 문제는 단순합니다. 초보자 책에서도 흔히 볼 수 있는 도형 그리기 문제입니다. 하지만 익숙한 문제를 익숙하지 않은 언어, 익숙하지 않은 방법을 사용해 해결해 보면 어떨까요? 자바, C#, 루비, 파이썬, 자바스크립트, 그루비, Erlang, 스칼라, ML, 해스켈(Haskell), 리스프, Io, 펄 등 다양한 언어를 이용해 다양한 방법으로 프로그램을 작성할 수 있을 것입니다.
  • 의도적으로 디자인 패턴을 마음껏 사용해 보는 것은 어떨까요?
  • 루비 등의 오리 타입(Ducking Type)을 한번 써보세요. 타입으로서 인터페이스는 과연 어떤 의미를 지니고 있는 것일까요?
  • 함수형 언어를 이용해 작성하면 프로그램이 어떤 모습이 될까요?
  • 자바스크립트로는 어떻게 프로그램을 구조화할 수 있을까요, 클래스 상속을 사용할까요, 프로토타입 기반 상속을 사용해 볼까요?

제가 자바로 작성해 본 간단한 예제가 있습니다. 어떤 언어, 어떤 방법도 좋습니다. 다양한 언어의 상상력에 여러분의 상상력을 더해 주세요.

마지막으로 여러분이 작성한 코드를 공유해 주세요. 블로그에 작성한 코드를 정리한 후, http://innolab.tistory.com/1173513751에 댓글이나 트랙백을 남겨주시거나 이메일(dwkorea@kr.ibm.com)로 보내주시면 됩니다. 창의적인 코드를 보내주신 분에게는 일정 기간에 한 번씩 선물도 드릴 예정입니다.



 
 



   
   
     
   
Listing 1. Shape.java
package codekata;

public interface Shape {
	public void draw();
	public void moveTo(int x, int y);
	public void moveBy(int dx, int dy);
}
 

Listing 2. AbstractShape.java
package codekata;

public abstract class AbstractShape implements Shape{
	protected int x;
	protected int y;
	
	public void moveTo(int x, int y){
		this.x = x;
		this.y = y;
	}
	
	public void moveBy(int dx, int dy){
		this.x += dx;
		this.y += dy;
	}
	
	public String toString(){
		return "[X : " + x + " Y : " + y + "]";
	}
}
 

Listing 3. Rectangle.java
Package codekata;

public class Rectangle extends AbstractShape{
	private int width;
	private int height;

	public Rectangle(int x, int y, int width, int height){
		this.x = x;
		this.y = y;
		this.width = width;
		this.height = height;
	}
	
	@Override
	public void draw() {
		System.out.println("Drawing Rectangle - " + this.toString());
	}
	
	public String toString(){
		return super.toString() + " [Width : " + this.width + ", Height : " + this.height + "]";
	}

	public int getWidth() {
		return width;
	}

	public void setWidth(int width) {
		this.width = width;
	}

	public int getHeight() {
		return height;
	}

	public void setHeight(int height) {
		this.height = height;
	}
}
 

Listing 4. Circle.java
Package codekata;

public class Circle extends AbstractShape{
	private int radius;
	
	public Circle(int x, int y, int radius){
		this.x = x;
		this.y = y;
		this.radius = radius;
	}

	@Override
	public void draw() {
		System.out.println("Drawing Circle - " + this.toString());
	}
	
	public String toString(){
		return super.toString() + " [Radius - " + this.radius + "]";
	}

	public int getRadius() {
		return radius;
	}

	public void setRadius(int radius) {
		this.radius = radius;
	}
}
 

Listing 5. Test.java
Package codekata;

public class Test {
	private static void doPolymorphicOp(Shape shape){
		shape.draw();
		shape.moveBy(10, 20);
		shape.draw();
		shape.moveTo(100, 130);
		shape.draw();
	}
	
	public static void main(String[] args) {
		Shape[] shapes = new Shape[]{new Rectangle(0, 0, 10, 15), new Circle(10, 10, 5)};
		
		for (Shape shape : shapes) {
			doPolymorphicOp(shape);
		}
	}
}
 
반응형

알고리즘은 아랍의 수학자 알콰리즈미 ( al-Khw ā rizm ī ) 의 이름에서 유래한 것으로 유한한 단계를 통해 문제를 해결하기 위한 절차나 방법을 말합니다. 쉽게 말해 어떤 문제를 해결하기 위해 사용 가능한 방법이란 뜻이죠. 여러분이 어떤 문제를 프로그래밍 언어를 통해 해결해 냈다면, 그 문제를 해결할 수 있는 한 가지 알고리즘 ( 문제 해결을 위한 절차 ) 을 찾아냈다고 보셔도 됩니다.

퀴즈 1. 프로시저 Both 를 완성해 봅시다.

우선 한 가지 문제를 해결해 볼까요? Listing 1 은 두 ArrayList 데이터 내에서 공통 원소만을 뽑아 모으는 프로시저, either 를 자바 언어를 이용해 만든 것입니다. 만일 두 ArrayList 내의 모든 원소를 합쳐 모으는 프로시저, both 가 필요하다면 어떻게 하면 좋을까요?

Listing1. FirstQuizSet
import java.util.*;
  public class FirstQuizSet {
    public static ArrayList both(ArrayList xs, ArrayList ys) {
      // TODO: 이 곳을 채우는 문제입니다.
    }

  public static ArrayList either(ArrayList xs, ArrayList ys) {
    ArrayList eitherList = new ArrayList();
    Object y = null; Iterator elems = ys.iterator();
    while (elems.hasNext()) {
      y = elems.next();
      if (xs.contains(y)) eitherList.add(y);
    }
    return eitherList;
  }

  public static ArrayList toArrayList(int[] xs) {
    ArrayList ys = new ArrayList();
    for (int i = 0; i < xs.length; i++) ys.add(new Integer(xs[i]));
    return ys;
  }

  public static void main(String[] args) {
    int[] xVec = { 1, 3, 4, 5, 6, 9, 7 };
    int[] yVec = { 4, 5, 8, 9, 10, 15, -1 };
    ArrayList xs = toArrayList(xVec); ArrayList ys = toArrayList(yVec);
    System.out.println( both(xs, ys) ); System.out.println( either(xs, ys) );
  }
}


Listing 1 의 실행 결과 예시
[1, 3, 4, 5, 6, 9, 7, 8, 10, 15, -1] ß both 의 실행 결과
[4, 5, 9] ß either 의 실행 결과

첫 번째 퀴즈인 both 를 해결하셨나요? 실행 결과는 제대로 나오구요? 축하드립니다.


 
 


퀴즈 2. 수행 속도를 높인 fastEither 를 만들어봅시다.

저는 부산 토박이라 서울에서 차를 몰고 어디로 이동해야 하는 상황이라면 항상 네비게이션의 힘을 빌립니다. 그런데 제가 사용하는 네비게이션은 항상 큰길 중심으로 길을 찾아줘서, 지름길을 알고 나면 그 동안 다녔던 길이 비효율적이였던 적이 많더군요. 20 분이면 도착할 거리를 50 분이나 걸려서 다녔던 적도 있습니다.

이처럼 목적지를 향해 가는 길은 하나만 있는 것이 아닙니다. 여러 가지 대안이 존재하기 마련이고, 각 대안마다 나름대로 장점과 단점이 있습니다. 그러므로 단지 그 문제를 해결했다고 해서 만족하는 것은 올바른 프로그래머의 자세가 아니라고 생각합니다. 좀 더 고급 개발자로 올라서려면 원하는 품질을 확보했느냐를 따져보는 습관이 중요합니다.

이번 문제에서 요구되는 품질이 성능이라고 가정해 봅시다. 성능을 중요하게 여기는 문제라면, 위에서 샘플 코드로 소개한 either 프로그램은 만족스럽지 않은 답입니다. 샘플 코드에서 xs 와 ys 가 이미 오름차순으로 정렬되어 있다고 가정하면 훨씬 빠른 프로시저를 만들 수 있기 때문입니다.

아래는 이 아이디어에 바탕을 두고 both 를 개선한 fastBoth 입니다. 같은 방식으로 fastEither 도 한번 만들어보세요. 물론 더 빨리 실행될 수 있도록 하는 아이디어가 생각났다면, 그 방식으로 구현해도 좋습니다.

Listing 2. FastEitherQuiz
public class FastEitherQuiz {
  public static ArrayList fastEither(ArrayList xList, ArrayList yList) {
    // TODO: 이곳을 채우는 문제입니다.
  }

  public static ArrayList fastBoth(ArrayList xList, ArrayList yList) {
    ArrayList bothList = new ArrayList();
    final int xSize = xList.size(); final int ySize = yList.size();
    Comparable x, y;
    int order; int xpos, ypos;
    xpos = ypos = 0;
    while ( xpos < xSize && ypos < ySize ) {
      x = (Comparable)xList.get(xpos); y = (Comparable)yList.get(ypos);
      order = x.compareTo(y);
      if (order == 0) {
        bothList.add(x); // or y
        ++xpos; ++ypos;
      } else if (order < 0) {
        bothList.add(x); ++xpos;
      } else {
        bothList.add(y); ++ypos;
      }
  }
  if (ypos == ySize) bothList.addAll( xList.subList(xpos, xSize) );
  else bothList.addAll( yList.subList(ypos, ySize) );
  return bothList;
  }

  public static void main(String[] args) {
    int[] xVec = { 1, 3, 4, 5, 6, 9, 7 };
    int[] yVec = { 4, 5, 8, 9, 10, 15, -1 };
    Collections.sort( xs ); Collections.sort( ys );  // 먼저 정렬을 한 다음,
    System.out.println( xs ); System.out.println( ys );
    System.out.println(fastBoth(xs,ys)); System.out.println(fastEither(xs,ys));
  }
}


Listing 2 의 실행 결과 예시
[1, 3, 4, 5, 6, 7, 9] ß xs 의 내용 
[-1, 4, 5, 8, 9, 10, 15] ß ys 의 내용 
[-1, 1, 3, 4, 5, 6, 7, 8, 9, 10, 15] ß fastBoth 의 결과 
[4, 5, 9] ß fastEither 의 결과 


다 완성했다면 얼마나 빨라졌는지 반드시 확인해야 합니다. 작성한 코드의 수행 속도를 계산할 수 있는 코드는 다음과 같습니다 ( 즐겨 사용하는 프로파일러가 있다면 해당 프로파일러를 사용해도 좋습니다 ). 과연 여러분이 기대한 만큼 성능이 향상됐나요? 그렇다면 이전 코드에 비해 몇 % 의 성능 향상을 얻으셨나요?


Listing 3. 작성한 코드의 수행속도 계산
long start = System.currentTimeMillis(); 
// 시간을 잴 코드
long end = System.currentTimeMills();long time = end-start;


이러한 성능 최적화를 수행할 때 주의해야 할 점이 몇 가지 있습니다.

1. 최적화가 필요하다고 확인되지 않았다면 코드를 최적화하지 않는 것이 좋습니다. 최적화에 투입하는 개발자의 노력 역시 중요한 자원이기 때문입니다. 그리고 무작정 “ 이 부분이 느린 것 같으니까, 이렇게 고치면 빨라질 거야 ” 라는 막연한 생각으로 덤벼 들면 안 됩니다. 직접 수행 시간을 확인하거나, 프로파일러를 통해 성능 개선이 필요한 부분을 점검하고, 성능 개선 목표를 정하고, 적용한 기법이 기대한 효과를 얻어 내는지 확인해야 합니다.

2. 최적화를 매우 신중하게 끝맺지 못했다면 버그가 있을 수 있습니다. 그러므로 수정한 코드가 정상적으로 동작함을 반드시 테스트해야 합니다. 늦더라도 정확하게 동작하는 코드가, 빠르면서 버그 있는 코드보다 나은 법입니다.

3. 무작정 빠른 코드를 만들기 위해 전체적인 설계를 깨트리는 일이 있어선 안 됩니다. 사소한 성능 이득을 취하기 위해, 설계 과정에서 고치거나 다루기 쉬운 구조로 잡아놓은 프로그램의 틀을 스스로 깨버려야 한다면, 잃는 것과 얻는 것을 면밀히 검토해야만 할 것입니다. 이런 불행을 피하기 위해서는 설계를 튼튼히 하는 수 밖에 없습니다. 개발 초기에 프로그램 설계나 자료구조, 알고리즘 선택에 집중하게 되면, 정작 코드를 더 빠르게 돌아가도록 고쳐쓸 때, 훨씬 더 쉽게 적은 비용으로 코드 수정이 가능하게 됩니다.

4. 유행하는 기법이나 잘 알려진 속설에 의존하기보다, 스스로 주어진 환경에서 검증된 결과를 믿어야 합니다. 비어있는 메서드나 죽은 코드 없애기, 압축 연산자 사용하기, 반복문에서 불변 코드 빼내기, 반복문 펼치기, String 대신 StringBuffer 사용하기, 어떤 수준의 컴파일 최적화 옵션 사용하기 등 잘 알려진 최적화 기법들이 과연 내가 사용하는 환경에서도 적용될까요? 어떤 기법들은 컴파일러가 알아서 해주는 것을 불필요하게 작업한 것도 있을 것이고, JVM 기술이 발전하면서 오히려 역효과가 나는 것도 있으며, 언어의 버전이 올라가면서 더 나은 최적화 기법이 고안된 경우도 있을 겁니다. 결국 제대로 된 최적화 작업을 수행하기 위해서는, 유연하고, 확장성이 쉬운 구조로 프로그램의 틀을 만드는 큰 관점의 시각과 런타임 최적화 원리나 VM 의 클래스 로딩 절차, 각종 최적화 기법과 그 적용 범위 등을 깊이 있게 이해하는 작고 깊이있는 관점의 시각이 균형감있게 제공되어야 할 것 같습니다.

이처럼 프로시저나 함수 수준에서 해결해야 할 문제라고 하더라도, 성능이라는 한 가지 주제가 더해지면 많은 생각을 하게 되는 문제로 바뀝니다. 데이터나 객체 수준으로 추상화 수준이 올라가고, 고려해야 할 품질 속성이 더 많아지면 그 복잡성이란 이루 말할 수 없겠죠? 그래서 프로그래머란 직업이 평생 학습과 훈련을 반복해야 하는 고된 전문직이라 말할 수 있는 게 아닐까요?

비슷한 유형의 퀴즈 두 개를 더 풀어보는 것으로 이번 연재를 마무리하겠습니다.



 
 


퀴즈 3. isSubstring 을 작성해 봅시다.

세 번째 퀴즈는 두 개의 배열을 받아 왼쪽 배열에 들어있는 문자열이 오른쪽 배열에 포함되어 있는지 검사하는 프로그램, isSubstring 을 작성하는 것입니다.

Listing 4. PatternTest
public class PatternTest {
  public static boolean isSubstring(char[] left, char[] right) { ... }
  public static void main(String[] args) {
    char[] first = { ’a’, ’b’, ’c’ };
    char[] second = { ’a’, ’c’, ’b’, ’c’};
    char[] third = { ’a’, ’a’, ’b’, ’c’};
    isSubstring( first, second ); // false
    isSubstring( first, third ); // true
  }
}



   


퀴즈 4. 프로시저 match 를 작성해 봅시다.

네 번째 퀴즈는 문자열이 들어있는 배열을 받아 열고 닫는 괄호 문자가 짝이 맞는지 검사하는 프로시저 match 를 작성하는 것입니다. 괄호 이외의 문자는 무시하도록 합니다.

Listing 5. MatchTest
public class MatchTest {
  public static boolean match(char[] cs) { ... }
  public static void main(String[] args) {
    char[] first = { ’(’, ’[’, ’<’, ’{’, ’}’, ’>’, ’]’, ’)’ };
    char[] second = { ’(’, ’[’, ’<’, ’{’, ’>’, ’}’, ’]’, ’)’ };
    char[] third = { ’(’, ’a’, ’c’, ’)’, ’[’, ’{’, ’}’, ’]’ };
    match(first); // yes
    match(second); // no
    match(third); // yes
  }
}

자신이 알고 있는 언어의 특성을 마음껏 발휘해 다양한 해답을 만들어 보는 것도 흥미로울 것 같습니다. C 나 리스프 (LISP), 파이썬, 자바스크립트, Haskell, 펄 (Perl), C#, 자바 등이 그 대안이 될 수 있겠죠? 두 가지 이상의 언어를 알고 있다면 두 개의 문제를 각각 다른 언어로 해결하고, 그 언어가 가지는 표현력과 특징이 문제를 해결하는 데 어떤 영향을 나에게 끼치고 있는지를 실험해 보기 바랍니다. 다양한 언어를 다룸으로써 그 언어가 제공하는 패러다임을 경험한 만큼 내 사고가 유연해진 것을 느낄 수 있을 겁니다.

마지막으로 여러분이 작성한 코드를 공유해 주세요. 블로그에 작성한 코드를 정리한 후, 제 블로그에 댓글이나 트랙백 (http://seal.tistory.com/trackback/150) 을 남겨주시거나 이메일 (dwkorea@kr.ibm.com) 로 보내주시면 됩니다. 창의적인 코드를 보내주신 분에게는 일정 기간에 한 번씩 선물도 드릴 예정입니다. 적극적인 참여로 한걸음씩 같이 발전해봅시다

반응형
사용자 삽입 이미지


요즘 Wide 모니터가 대세(?)죠?!
이렇게 넓은 모니터를 쓰다보면 창을 반으로 쪼개서 쓰고 싶을 때가 많은데
이럴 때, 유용한 툴을 소개합니다.

툴 이름은 WinSplit Revolution이고, http://reptils.free.fr/ 에서 다운받을 실 수 있습니다.

사용법이나 해주는 동작도 간단합니다.

(CTRL) + (ALT) + [NUM PAD] 를 누르면 되는데.. 현재 창이 아래와 같은 방향으로 이동/축소 됩니다.

사용자 삽입 이미지











한가지 더 막강한 기능은 듀얼 모니터 지원 기능입니다.

듀얼 모니터에서 (CTRL) + (ALT) + (→) 를 누르거나 (CTRL) + (ALT) + (←)를 누르면 창이 옆의 모니터로 이동합니다. 듀얼 모니터를 쓰시는 분은 이 기능이 왜 필요한지 바로 아실 것 같네요 :)
반응형

데스크탑 분할 프로그램. 모니터가 한 개인 상태에서 여러개의 창을 분류별로 각 데스크탑에 나눠 두면 작업 효율성이 향상된다. 유닉스 계열의 X-Window에 기본적으로 있는 기능인데, 윈도우에서 그것을 흉내낸 프로그램이다.

마우스 드래그로 데스크탑간 이동도 되고

단축키를 이용한 이동도 가능하고 ㅎ

메모리 점유율은 5메가 정도

사용자 삽입 이미지


사용자 삽입 이미지


사용자 삽입 이미지


http://virtuawin.sourceforge.net/     <-- 다운로드
반응형
top 이미지
date   지난 뉴스레터 보기
hot clip

객체 지향론자를 위한 함수 프로그래밍
hot clip 이미지 이 번에 시작하는 연재에서는 함수와 객체 지향 기법을 혼합한 JVM을 위한 프로그래밍 언어인 스칼라를 소개합니다. 언어 소개와 함께 동시성(concurrency) 등 굳이 스칼라를 배워야 하는 이유를 설명하고, 스칼라를 얼마나 빨리 써먹을 수 있는지를 살펴봅니다.

로컬 컨텐츠
테러리스트에서 버그까지 dW Column
루비 메타프로그래밍 part 2 : eval 메서드 Open dW
코드 트레이닝 part 2 - 알고리즘과 성능Special Issue
오픈 소스로 재미 이상의 가치를 전달하기 dW interview
[기획기사] 동적인 언어를 동적으로 호출하기

SW 다운로드
Rational Developer for System z 시험판
Lotus Forms V3.0.1 업데이트
WebSphere Business Modeler Advanced V6.1.1 업데이트
Lotus Domino 8 시험판
DB2 Express-C 9.5 무료 제품

기술자료 & 튜토리얼
리눅스 네트워킹 스택 분석
E4X와 Prototype으로 구현하는 Ajax 스무고개 게임, Part 2
클래스 동작
LAMP 시스템 조율, Part 1
메모리 디버깅 기법
IBM Lotus Expeditor에서 안전한 웹 서비스 개발하기
Ajax와 딜리셔스(del.icio.us)로 자신만의 정보 공간을 만들자튜토리얼
셀/B.E. 컨테이너 가상화, Part 1
LAMP 시스템 조율, Part 2
javax.tools를 이용한 동적 애플리케이션 생성
메모리 프로그래밍을 개선하자
이클립스 플러그인이 OSGi에서 어떻게 동작하는지 이해하기
IBM Information Server를 사용한 SAP NetWeaver Business Intelligence와 데이터 통합
이클립스로 비즈니스 프로세스 실행하기튜토리얼

공지사항
초보 개발자 코드 트레이닝
dW 스페셜 이슈에서는 독자들이 정답이라는 압박에서 벗어나 창의력 있게 문제를 풀 수 있는 기회를 제공합니다. 프로그래밍 기술을 향상시킬 수 있는 문제 풀이에 적극 참여해보세요.
 
Academic Initiative 배너
 
dW 커뮤니티 배너
 
기획기사 배너
 
SOA Sandbox 배너
 
dW 컬럼 배너

뉴스레터 추천하기
하단 배너
반응형

사이버 공간에 떠다니거나 잠자고 있는 자신의 주민등록번호를 정리할 수 있게 되었다.

행정안전부(장관 원세훈)는 사이버 상의 주민등록번호 오·남용 방지 및 안전한 사용을 유도하기 위하여 오는 5월 1일부터 6월 30일까지 두 달간 행정안전부와 함께하는『2008 주민번호 클린 캠페인』- 나도 모르게 떠다니는 ’내 주민번호를 찾아라!!‘ - 를 실시한다.

『주민번호 클린 캠페인』은 누구나 참여 가능하고, 개인의 프라이버시 보호를 위하여 공인인증서, 신용카드, 주민등록정보 인증 등 온라인상의 본인 인증절차를 거쳐 참여할 수 있다.

2007년에 이어 두 번째 실시하는 이번 캠페인은, 최근 개인정보에 대한 국민적 관심과 우려가 집중되고 있어 행정안전부가 사이버 상에 떠도는 자신의 주민번호 이용내역을 확인해 줌으로써 개인정보 보호의식을 높이고 자기정보를 스스로 잘 관리할 수 있도록 도와주기 위한 것으로, 2001년부터 실명확인서비스 이후 인터넷 사이트에서 실명확인 및 성인인증 등의 목적으로 자신의 주민번호가 언제, 어디서 사용 되었는지 주민등록번호 이용내역을 무료로 확인해 주고 개인정보 보호 대처방안 등도 함께 안내할 계획이다.

※ ‘주민번호 이용내역 확인서비스’ 란 ?
 ‘신용정보이용 및 보호에 관한 법률‘ 등에 의거 금융 거래시 본인 동의로 수집·보유하고 있는 신용평가회사의 신용정보DB를 이용하여 인터넷사이트에 실명확인 등의 목적으로 제공된 주민번호 이용내역을 인터넷으로 열람해 주는 서비스임

특히, 이번 캠페인에서는 본인 인증수단으로 공인인증서, 신용카드 인증 이외에 본인 인증수단을 확보하기 어려운 청소년(20세이하)과 고령자(60세이상) 들에게 참여기회를 제공하기 위하여 행정안전부의 주민등록전산정보센터가 보유하고 있는 주민자료의 “세대주의 생년월일, 성명, 증 발급일자”를 이용한 본인 인증수단을 새롭게 마련하여 캠페인 참여기회를 확대 하였다.

청소년과 고령자에게만 주민등록정보를 본인 인증수단으로 제공하는 것은 본인 외의 가족이 이용내역을 확인하여 가족 간의 프라이버시가 침해될 우려가 있기 때문에 부득이 청소년과 고령자에게만 주민등록정보를 이용하게 하였다.

또한, 캠페인 화면에서 자신의 주민번호가 이용된 사이트에 직접 접속이 가능하도록 링크를 지원하고, 인터넷기업협회 회원사에 대하여 자신의 휴면계정(ID)을 전화로도 탈퇴 신청이 가능하도록 하는 한편, 이번 캠페인에 협력하고 있는 3개 실명확인제공기관(한국신용평가정보, 한국신용정보, 서울신용평가정보)의 실명확인제공로그 기록도 본인이 선택적으로 삭제할 수 있도록 하였다.


캠페인 참여방법은

클린캠페인 전용페이지(http://clean.mopas.go.kr) 나,
행정안전부의 대표 블로그 2곳(네이버 블로: blog.naver.com/happymopas, 다음 블로그: blog.daum.net/happymopas)
행정안전부(www.mopas.go.kr), G4C(www.egov.go.kr), 대한민국 전자정부(www.korea.go.kr), 시·도 및 시·군·구의 홈페이지 등에 접속하여 ‘주민번호 클린 캠페인’ 참여하기를 이용하면 된다.


※ ‘캠페인 참여하기' 팝업/배너 링크주소 : http://clean.mopas.go.kr

한편, 각종 포털 등(나우콤, 네오위즈, 넥슨, 다음, 드림위즈, 에스케이- 커뮤니케이션즈, 엔씨소프트, 엔에이치엔, 옥션, 씨제이인터넷, 케이티- 에이치, 코리아닷컴, 하나로드림) 에서도 캠페인에 참여할 수 있다.


캠페인 참여 절차는

① 캠페인 전용페이지 등 각종 홈페이지 ‘캠페인 참여하기’에 접속하여
② ‘주민번호 이용내역 확인서비스 제공기관’을 선택하고
③ 자신의 주민번호 입력 후 본인인증(공인인증서, 신용카드, 주민등록정보 인증 중 택일) 절차를 거쳐
* 프라이버시 보호를 위하여 본인 인증을 거쳐 조회서비스 제공
④ 사이버 상에서 실명확인 등에 사용된 ‘주민번호 이용내역’을 조회한다.
⑤ 필요시 본인의 의사결정에 따라 해당사이트를 방문하여 휴면 계정(ID, 주민번호) 정리 등 개별적인 조치를 할 수 있다


< 사이버 상의 본인인증 방법 및 절차 >
① 공인인증서 인증 : 금융결제원 등 6개 공인인증기관에서 발행한 인증서
   - (하드디스크 또는 USB에 저장된)공인인증서와 비밀번호로 인증
② 신용카드 인증 : 신용카드 결제처리와 같은 방식의 인증
  - 신용카드번호 + 유효기간 + 카드비밀번호 2자리 등으로 인증
③ 주민등록정보 인증 : 20세이하(‘88.1.1이후 출생), 60세이상(’49.1.1이전 출생)으로서 공인인증서나 신용카드를 보유하고 있지 않는 대상자
  - 세대주 정보(생년월일 + 성명 + 증발급일자) 등으로 인증

< 인터넷 사이트의 회원 탈퇴 절차 >
+ 회원 탈퇴는 본인이 의사 표시를 할 경우 어떤 방법으로든 탈퇴 가능
  - 각 사이트의 고객센터 페이지에서 또는 전화 등으로 의사표시
+ 탈퇴 절차는
  - ID와 비밀번호를 아는 경우 : 별도의 신원확인 절차 없이 탈퇴 가능
  - ID와 비밀번호를 모를 경우 : 신원확인 절차(공인인증서, 휴대폰인증, 신분증사본의 우편·Fax송부, 주민등록증 진위확인절차를 활용한 전화로 요청 등) 필요
※ 회원 탈퇴시 해당사이트의 개인 자산(사이버머니, 블로그, 개인홈페이지, e-메일 등)이 삭제되므로 재산권 분쟁 방지를 위해 신원확인 조치 불가피 의견 (사이트운영기관)


캠페인을 통해 확인할 수 있는 서비스 내용은 3개의 실명확인제공기관을 이용하여 2001년 이후 인터넷 사이트에서 ‘실명확인 및 성인인증’ 등의 목적으로 주민등록번호를 이용한 내역(이용일자, 사이트명, 사이트 구분, 이용목적 등)들을 온라인 상에서 화면으로 확인 할 수 있다.

<예>

 이용한 날짜  이용한 사이트명  사이트 구분  이용목적
 2005.  3. 27  www.naver.com  포털  회원가입
 2004. 12. 15  www.hangame.com  게임  기존회원조회

※ 실명확인제공기관(3개사)을 통해 확인 가능한 사이트 수는 약 2만개 정도

이번 캠페인은 한국인터넷기업협회(+ 회원사에 ‘캠페인 링크/홍보’ 지원), 실명확인제공기관(한국신용평가정보·한국신용정보·서울신용평가정보 - + 그간의 실명확인제공자료를 통한 ‘주민번호 이용내역 확인서비스’ 무료지원) 등의 협조를 받아 함께한다.

앞으로도 행정안전부에서는 주민등록번호의 올바른 사용을 유도하고 개인정보의 오·남용 방지를 위하여 클린캠페인을 정기적으로 실시할 계획이다.


[참고자료]
 1. 주민번호 클린 캠페인 메인페이지 구성도
 2. 주민번호 클린 캠페인 참여가능한 사이트 및 참여방법
 3. 주민번호(명의) 도용 사례


담당 : 주민제도과 / 02-2100-3988

반응형

10진수

16진수

8진수

2진수

ASCII

10진수

16진수

8진수

2진수

ASCII

0

0×00

000

0000000

NULL

64

0×40

100

1000000

@

1

0×01

001

0000001

SOH

65

0×41

101

1000001

A

2

0×02

002

0000010

STX

66

0×42

102

1000010

B

3

0×03

003

0000011

ETX

67

0×43

103

1000011

C

4

0×04

004

0000100

EOT

68

0×44

104

1000100

D

5

0×05

005

0000101

ENQ

69

0×45

105

1000101

E

6

0×06

006

0000110

ACK

70

0×46

106

1000110

F

7

0×07

007

0000111

BEL

71

0×47

107

1000111

G

8

0×08

010

0001000

BS

72

0×48

110

1001000

H

9

0×09

011

0001001

HT

73

0×49

111

1001001

I

10

0×0A

012

0001010

LF

74

0×4A

112

1001010

J

11

0×0B

013

0001011

VT

75

0×4B

113

1001011

K

12

0×0C

014

0001100

FF

76

0×4C

114

1001100

L

13

0×0D

015

0001101

CR

77

0×4D

115

1001101

M

14

0×0E

016

0001110

SO

78

0×4E

116

1001110

N

15

0×0F

017

0001111

SI

79

0×4F

117

1001111

O

16

0×10

020

0010000

DLE

80

0×50

120

1010000

P

17

0×11

021

0010001

DC1

81

0×51

121

1010001

Q

18

0×12

022

0010010

SC2

82

0×52

122

1010010

R

19

0×13

023

0010011

SC3

83

0×53

123

1010011

S

20

0×14

024

0010100

SC4

84

0×54

124

1010100

T

21

0×15

025

0010101

NAK

85

0×55

125

1010101

U

22

0×16

026

0010110

SYN

86

0×56

126

1010110

V

23

0×17

027

0010111

ETB

87

0×57

127

1010111

W

24

0×18

030

0011000

CAN

88

0×58

130

1011000

X

25

0×19

031

0011001

EM

89

0×59

131

1011001

Y

26

0×1A

032

0011010

SUB

90

0×5A

132

1011010

Z

27

0×1B

033

0011011

ESC

91

0×5B

133

1011011

[

28

0×1C

034

0011100

FS

92

0×5C

134

1011100

\

29

0×1D

035

0011101

GS

93

0×5D

135

1011101

]

30

0×1E

036

0011110

RS

94

0×5E

136

1011110

^

31

0×1F

037

0011111

US

95

0×5F

137

1011111

_

32

0×20

040

0100000

SP

96

0×60

140

1100000

.

33

0×21

041

0100001

!

97

0×61

141

1100001

a

34

0×22

042

0100010

"

98

0×62

142

1100010

b

35

0×23

043

0100011

#

99

0×63

143

1100011

c

36

0×24

044

0100100

$

100

0×64

144

1100100

d

37

0×25

045

0100101

%

101

0×65

145

1100101

e

38

0×26

046

0100110

&

102

0×66

146

1100110

f

39

0×27

047

0100111

'

103

0×67

147

1100111

g

40

0×28

050

0101000

(

104

0×68

150

1101000

h

41

0×29

051

0101001

)

105

0×69

151

1101001

i

42

0×2A

052

0101010

*

106

0×6A

152

1101010

j

43

0×2B

053

0101011

+

107

0×6B

153

1101011

k

44

0×2C

054

0101100

'

108

0×6C

154

1101100

l

45

0×2D

055

0101101

-

109

0×6D

155

1101101

m

46

0×2E

056

0101110

.

110

0×6E

156

1101110

n

47

0×2F

057

0101111

/

111

0×6F

157

1101111

o

48

0×30

060

0110000

0

112

0×70

160

1110000

p

49

0×31

061

0110001

1

113

0×71

161

1110001

q

50

0×32

062

0110010

2

114

0×72

162

1110010

r

51

0×33

063

0110011

3

115

0×73

163

1110011

s

52

0×34

064

0110100

4

116

0×74

164

1110100

t

53

0×35

065

0110101

5

117

0×75

165

1110101

u

54

0×36

066

0110110

6

118

0×76

166

1110110

v

55

0×37

067

0110111

7

119

0×77

167

1110111

w

56

0×38

070

0111000

8

120

0×78

170

1111000

x

57

0×39

071

0111001

9

121

0×79

171

1111001

y

58

0×3A

072

0111010

:

122

0×7A

172

1111010

z

59

0×3B

073

0111011

;

123

0×7B

173

1111011

{

60

0×3C

074

0111100

<

124

0×7C

174

1111100

|

61

0×3D

075

0111101

=

125

0×7D

175

1111101

}

62

0×3E

076

0111110

>

126

0×7E

176

1111110

~

63

0×3F

077

0111111

?

127

0×7F

177

1111111

DEL


+ Recent posts