2009/05/23 17:21

▦▦ 슬프다. 원통하다. 그리고 창피하다. ▦▦

당신께서 이젠 같은 하늘아래 있지 못해서 슬픕니다.
그렇게까지 만든 쓰레기 같은 것들 때문에 원통합니다.
그리고 제 자식에게 훗날 뭐라고 어떻게 설명해야 할지... 그래서 창피합니다.

난, MB가 될 때 마음 먹은 것들이 있다.
다시는 한국에서는 교회에 나가지 않겠다.
그리고, 무조건 이 나라를 떠나기 위해서 준비하겠다.
또...
또...
너무나 다짐한게 많다.
그런데, 아마도 더욱 간절히 다짐하고 철저히 준비할 것 같다.

마지막 한 마디, "담배 있나?" 얼마나 마지막 가는 그 길이 외로워겠나?
나이 칠순을 바라보는 예순을 넘은 노인네가 얼마나 고통스러웠으면 죽음을 택했겠는가?
아... 정말 이나라가 역겹다. 역겨워... 쓰레기를 치워도 치워도 또 나올 이 나라!

무섭다. 이나라가... 돈에 미쳐가는 인간들하며 생명을 아무렇지도 않게 다루는 이 나라.
미쳤다... 다들 미쳤어. 이기적임을 떠나 인간임을 거부하는 이나라...가 너무 싫다.
아직도 가슴이 뛴다. 당신이 없는 이나라가 너무 싫다.

부끄럽다.
자꾸 눈물이 나온다.
너무나 눈물이 나온다.

그 동안 너무나 고마웠고, 수고하셨습니다.
먼 곳에서라도 편안해지길 바랍니다.

추신:
블로거들에게
노 전 대통령에 관해서, 진실하고 진지하며, 사실적인(누구나 무엇이 진실이 압니다.) 포스트가 자신의 블로그에 저장되기를 바랍니다. 먼 훗날 단 1개라도 노 대통령에 대한 글이 후손들에게 보여지길 바라기 때문입니다. 시간이 갈수록 가슴이 더 아려옵니다. 그리고 시간이 또 지나면 그가 잊혀질까봐 두렵습니다.

언론이 보도한 유서

너무 많은 사람들에게 신세를 졌다
나로 말미암아 여러 사람이 받은 고통이 너무 크다.
앞으로 받을 고통도 헤아릴 수가 없다.
여생도 남에게 짐이 될 일 밖에 없다.
건강이 좋지 않아서 아무 것도 할 수가 없다.
책을 읽을 수도 글을 쓸 수도 없다.
너무 슬퍼하지 마라.
삶과 죽음이 모두 자연의 한 조각 아니겠는가?
미안해 하지 마라.
누구도 원망하지 마라.
운명이다.
화장해라.
그리고 집 가까운 곳에 아주 작은 비석 하나만 남겨라

언론에서 보도 하지 않은 유서 뒷 부분

사는 것이 힘들고 감옥같다.
나름대로 국정을 위해 열정을 다했는데 국정이 잘못됐다고 비판 받아 정말 괴로웠다.
지금 나를 마치 국정을 잘못 운영한 것처럼 비판하고 지인들에게 돈을 갈취하고, 부정부패를 한것처럼 비쳐지고, 가족 동료, 지인들까지 감옥에서 외로운 생활을 하게 하고 있어 외롭고 답답하다.

아들 딸과 지지자들에게도 정말 미안하다.
퇴임후 농촌 마을에 돌아와 여생을 보내려고 했는데 잘 되지 않아 참으로 유감이다.

돈 문제에 대한 비판이 나오지만 이 부분은 깨끗했다. 나름대로 깨끗한 대통령이라고 자부 했는데 나에 대한 평가는 멋 훗날 역사가 밝혀줄 것이다.



사진으로 보는 노 전 대통령의 인생모습1


사진으로 보는 노 전 대통령의 인생모습2



의혹의 끝은 어딜꼬?


풀리지 않는 의혹들


퍼옴


강금원이라는 사람(퍼옴)


노무현 대통령은 절대! 돈을 받지 않았다.


노무현 대통령 임기시기 업적


우리는 지금 타살설이 아니라 도청설에 주목해야 합니다.


부끄러운줄 알아야지


부시가 똑똑해 보일 때


노무현 대통령이 이명박에게 쓴 편지 + 한나라당 대변인 쓴 답장


노무현 대통령 자이툰 부대 방문기



저작자 표시
Trackback 1 Comment 5
2009/05/18 10:28

이클립스 프로젝트 필수 유틸리티

이클립스 프로젝트 필수 유틸리티 : subversion, Ant, JUnit, Trac - 6점
민진우 외 지음/한빛미디어

읽은 목적: 도구 활용의 극대화를 위해
학습수준: 완전 초보
학습기간: 4일

별 3개의 이유(사실 2개나 1개를 주고 싶다. ^^)

별을 넉넉히 주고 싶지 않다. 2개 정도 주고 싶은데, 이 만큼 이클립스 관련 유틸리티를 정리한 책이 없지 싶다. 그래서 별 3개를 줬다. 1판은 보지 않아서 비교 대상은 아니다.

소개

이클립스를 통해 자바 개발을 하는 사람을 위해 최소한(?)의 툴을 소개한다. 사실 이쯤 되면 부연하고 싶은 것은 이클립스는 정확하게 자바 툴이 아니다. 개발을 하기 쉽게 하기 위해서 이클립스라는 아키텍쳐에 자바 개발 플러그인이 꼽힌 것이다. 물론 이클립스 자체가 자바로 개발을 했다. 그렇기 때문에 더 친근한 것은 맞지만서도 정확성을 따지면 이클립스 개발 생산성을 위한 아키텍쳐라고 말하고 싶다. 어쨌든, 그런 자바 개발 생산성을 높이기 위해서 CVS, SVN, JUnit, ANT, Trac 등의 사용법을 서술한다.

전문가의 기본? 기준?

요즘 대부분 SVN, JUnit, ATN 정도의 3가지 툴은 기본인 것 같다. 제대로 사용하느냐 마느냐는 개발자나 해당 팀의 시스템 몫이고. 개인적으로 ALM에 관심이 많고 툴 사용하는데 관심이 많다. 아주 오래 전 얘긴데, 툴을 사용하면 초보자이고 에디터를 사용하거나 vi를 사용하면 전문가라는 기준을 내세운 고참이 있었다. (그지 같은 넘이었다. ^^) 원시시대에도 도구를 만들어 사용해서 보다 나은 환경을 만들어가려고 했는데, 무슨 개소린가 했다.

하지만 내가 보기에는 툴이 하는 것을 사람이 직접 해 봄으로서 작동원리 등을 이해하는데 있어서는 툴을 사용하지 않는 것이 옳은 것이지, 그게 전문가의 기준을 논하는 것은 잘 못 된 것 같다. ^^ 다들 공감을 하겠지만. 물론 그 때 내가 툴맹이라고 놀렸다. ㅎㅎ 그런데, 우리 팀에서 툴맹이 있다. (불만만 많은 넘이다.)

툴을 사용하면 생산성은 높아지는 것은 당연하다. 물론 툴에 대한 학습에 대한 side effect가 있겠지만. 또, 간혹가다가 툴의 버그로 인해 삽질 할 때도 있지만 그것을 말하고자 하는 것이 아니기에 패쓰! 내가 보기에는 툴을 쓰는 것이 복잡한 시스템 하에서는 기본인 것 같다.

책의 내용

책은 SVC(Soruce Verson Control)을 설명을 하고 빌드 자동화에 대한 설명, 그리고 JUnit Framework을 통한 초보적인 개발 방법을 4.x 그리고 3.x 버전을 모두 설명한다. 하나만 설명하면 될 것을 2개를 설명할 이유가 별로 없어 보이는데, 저자의 친절함에 의문이 든다. 후반부는 Trac이라는 오픈 소스인 이슈관리시스템(위키기반)을 설명한다.

저자는 책의 저술을 "조엘 온 소프트웨어" 책의 "조엘 테스트; 더 나은 코드를 위한 12단계" 라는 좋은 소프트웨어 개발팀 판단 기준에 따라 머리말을 풀어갔다. 하도 이 책을 읽은지 오래되서 기억이 나지 않지만 관리자급 이상이면 읽어봐야 되지 않나 싶다. 잠깐 소개를 하면 다음과 같다. 아래는 내 답이다. ^^


  1. 당신은 소스 컨트롤(버전 관리)을 사용하는가?
    • 그렇다. 이전회사도 그렇고 지금회사도 이것은 사용한다.
  2. 당신은 한 번에 빌드를 할 수 잇는가?
    • 이미 ANT 스크립트가 작성되어 있다. 그런데, 수정이 꼭 필요하다. ^^
  3. 당신은 매일 빌드를 수행하는가?
    • 이클립스는 자동 빌드 지원을 하고 나는 그것을 현재 체크해 놓았다.
  4. 당신은 버그 데이터베이스(버그 관리 시스템)가 있는가?
    • 없다. 이전회사는 있었는데, 지금 회사는 없다. 그래서 구축해서 하고 싶은데...
  5. 당신은 새 코드를 만들기 전에 버그를 모두 수정하는가?
    • 무조건이다.
  6. 당신은 최신의 스케줄을 유지하는가?
    • 나름대로 Mylyn을 통해서 업무에 대해서는 스케줄링을 유지한다.
  7. 당신은 스펙이 있는가?
    • 스펙의 범위가 넓지만 고객 요구사항은 가지고 있고, 없으면 개발하지 않는다.
  8. 프로그래머들은 조용한 환경에서 일하고 있는가?
    • 나름 조용한 회사다.
  9. 가능한 최상의 도구를 사서 쓰고 있는가?
    • 새로 나온 도구에 민감하다. 마치 개발 도구에 대한 early adapter라고 할 수 있다.
  10. 테스트 인력이 있는가?
    • 없다. 지랄 맞다. 이게...
  11. 면접 때 지원자들이 코드를 작성할 수 있는지 테스트 하는가?
    • 나는 코딩 테스트 2시간을 넘게 하고 입사했다.
  12. 복도에서 사용성 테스트를 하는가?
    • 이것을 복도에서 하는지 모르겠다. ^^

아쉬운 점

왜 SVN 설명 하는데, 또 CVS를 설명하는지 모르겠다. 그냥 SVN만 설명해도 되잖아. 괜히 지면 낭비다. 저자는 SVN이 대세라고 했으면서도 고전인 CVS를 설명한다. 내용이 중복된다면 하나의 툴에 집중해도 좋았을 것 같다. 나도 SVN은 우리회사에서 처음 써보지만, 이전 다른 것들과 큰 차이는 없다. (철학에 따라 다르지만)

다른 아쉬운 점은 Trac의 대한 설명이다. 사실, 이 툴은 설치 방법이 악랄하기로 유명하다. 오죽하면 시간이 남아도는 사람은 해보라는 말이 나오겠나? 다른 챕터는 유닉스/리눅스 설치에 대해 설명을 하고서는 유독 Trac은 설명하지 않는다. 아무래도 저자가 운영(?)하는 프로젝트인 TOW를 자랑할려고 하는 것인가?  아니면 저자의 블로그에라도 설명을 해 놓아야 되지 않았을까 싶다.

결론

나쁜 책은 아니지만 좋은 책도 아니다. 하지만, 책 값 때문에 비추다. 내용에 비해 책 값은 너무 비싸다. 24,000원씩할 정도의 가격은 아니라는 말이지. 그런데 더 나쁜 경우는 한빛 미디어에서 자바지기 박재성씨가 쓴 "자바 프로젝트 필수 유틸리티"(클릭)라는 책이 얼마 이후에 바로 출간 했다는 것이다. 참 우울하다. 왜냐하면 차례를 보아하니 그 책이 훨씬 더 가치가 있을 거라고 느끼기 때문이다. 좀 늦게 구입했다면 이 책보다는 그 책을 샀을 것이니까. (책 광고 아니다. 그저 이책 내용이 별로라는 얘기다.)


저작자 표시

'읽은 책 > 2009' 카테고리의 다른 글

이클립스 프로젝트 필수 유틸리티  (0) 2009/05/18
Head First Design Patterns  (0) 2009/04/28
UML, 실전에서는 이것만 쓴다  (0) 2009/04/09
부자가 되는 과학적 방법  (1) 2009/03/31
Inside Steve's Brain  (0) 2009/03/06
내 아이를 위한 비폭력 대화  (1) 2009/02/19
Trackback 0 Comment 0
2009/05/14 15:49

String.split() vs. StringTokenizer() in Java

문자열 테스트 할 것이 있어서 2개를 비교하게 됐다. 솔직히, 2개가 똑같은 녀석인지 알았다.
그런데 API 문서를 읽어보니 뭔가 다른 냄새가 난다.

보통 이런 코드에 대한 것은 검색하기 전에 나는 문서를 읽는 편이고 테스트를 해보는 편이다. 하도 찌라시 같은 정보가 많아서... (물론 내 정보도 찌라시일 가능성 "100% 입니다.!" ㅎㅎ)

역시나 다르다. 달라... ^^
split는 delimeter 로 나눈 자리에 비어 있으면, 빈 문자열을 만들어 배열로 리턴하지만,
StringTokenizer는 그 딴거 없이 delimeter에 따라 나눠서 빈 자리는 빼고 리턴한다.
아래 코드를 돌려보면 뭔 소린지 알거다.

또 다른 점은 마지막 delimeter 자리다.
위에서 말한 것처럼 비어 있으면 split는 빈 문자열이라도 만들어서 리턴한다고 했다.
하지만 마지막 자리가 비어 있으면 split도 StringTokenizer랑 똑같다.

하지만, 그것을 방지하기 위해서 split overload 메쏘드가 존재한다.
3번째, 4번째 테스트가 그렇다.

또한 성능은 때에 따라서 또 환경에 따라서 다르지만 누가 StringTokennizer가 더 느리다고 했던가? (사실, 우리팀장이...^^) String.split( "delemeter", -1) 주면 split가 더 느리게 나오는 경우가 더 많았다. 믿던지 말던지.
참고로 Split은 내부적으로 정규 표현식을 쓰고 StringTokenizer 직접 문자열을 분해한다.

하여간 아래코드를 보면 더 이상 설명을 하지 않아도 될 듯.
참 여기서 Java 5에서 제공하는 System.nanoTime()을 썼다.
System.nanoTime()이 System.currentTimeMillis()보다 정확하다고 한다.
당연하겠지. nano인데... 그럼 10-9승인가? 모르겠다.


import java.util.StringTokenizer;

public class StringTokenizerTest {
	private String str1 = "zero,one,two,three,four,five,six,seven,eight,nine";
	private String str2 = "zero,one,two,three,,five,six,seven,eight,nine";
	private String str3 = "zero,one,two,three,four,five,six,seven,eight,";
	private String str4 = ",one,two,three,four,five,six,seven,eight,nine";
	
	public static void main(String[] args) {
		StringTokenizerTest stt = new StringTokenizerTest();
		stt.doTest();
	}

	private void doTest() {
		String[] values1 = str1.split( "," );
		StringTokenizer values2 = new StringTokenizer( str1, "," );
		
		for (int i = 0, length = values1.length; i < length; i++) {
			System.out.println( "String[" + i + "]" + values1[ i ] );
		}
		
		System.out.println( "---------------------------------------" );
		for (int i = 0; values2.hasMoreTokens(); i++) {
			System.out.println( "String[" + i + "]" + values2.nextToken() );
		}
		
		System.out.println( "==============================================" );
		
		String[] values3 = str2.split( "," );
		StringTokenizer values4 = new StringTokenizer( str2, "," );
		
		for (int i = 0, length = values3.length; i < length; i++) {
			System.out.println( "String[" + i + "]" + values3[ i ] );
		}
		
		System.out.println( "---------------------------------------" );
		for (int i = 0; values4.hasMoreTokens(); i++) {
			System.out.println( "String[" + i + "]" + values4.nextToken() );
		}
		
		System.out.println( "==============================================" );		
		
		long startTime1 = System.nanoTime();
		String[] values5 = str3.split( "," );
		for (int i = 0, length = values5.length; i < length; i++) {
			System.out.println( "String[" + i + "]" + values5[ i ] );
		}
		long end1 = System.nanoTime();
		System.out.println( end1 - startTime1 );
		
		System.out.println( "---------------------------------------" );
		StringTokenizer values6 = new StringTokenizer( str3, "," );
		long startTime2 = System.nanoTime();
		for (int i = 0; values6.hasMoreTokens(); i++) {
			System.out.println( "String[" + i + "]" + values6.nextToken() );
		}
		long end2 = System.nanoTime();
		System.out.println( end2 - startTime2 );
		
		System.out.println( "---------------------------------------" );
		String[] values7 = str3.split( ",", -1 );
		long startTime3 = System.nanoTime();
		for (int i = 0, length = values7.length; i < length; i++) {
			System.out.println( "String[" + i + "]" + values7[ i ] );
		}
		long end3 = System.nanoTime();
		System.out.println( end3 - startTime3 );
		
		System.out.println( "==============================================" );		
		
		long startTime4 = System.nanoTime();
		String[] values8 = str4.split( "," );
		for (int i = 0, length = values8.length; i < length; i++) {
			System.out.println( "String[" + i + "]" + values8[ i ] );
		}
		long end4 = System.nanoTime();
		System.out.println( end4 - startTime4 );
		
		System.out.println( "---------------------------------------" );
		StringTokenizer values9 = new StringTokenizer( str4, "," );
		long startTime5 = System.nanoTime();
		for (int i = 0; values9.hasMoreTokens(); i++) {
			System.out.println( "String[" + i + "]" + values9.nextToken() );
		}
		long end5 = System.nanoTime();
		System.out.println( end5 - startTime5 );
		
		System.out.println( "---------------------------------------" );
		String[] values10 = str4.split( ",", -1 );
		long startTime6 = System.nanoTime();
		for (int i = 0, length = values10.length; i < length; i++) {
			System.out.println( "String[" + i + "]" + values10[ i ] );
		}
		long end6 = System.nanoTime();
		System.out.println( end6 - startTime6 );
	}
}
저작자 표시 비영리 변경 금지
Trackback 0 Comment 7