2013의 게시물 표시

자바 프로그래머에서 개발자로

  예전 직장에서 개발자 대상의 뉴스레터에 기고한 글입니다. 글 작성일: 2004년 7월 --- 자바 프로그래머에서 개발자로 우리는 개발자와 프로그래머라는 말을 뚜렷하게 구분하여 사용하고 있지는 않다. 하지만, 썬에서 발급하는 자바 자격증을 보면, SCJP, SCJD, SCAJ 등으로 구분하여, 프로그래머(Programmer), 개발자(Developer), 아키텍트(Architect)의 3단계로 구분하고 있다. 이 순서대로 경력과 능력이 올라가야 그 수준을 달성하게 된다. 즉, 개발자와 프로그래머 사이에서는 개발자가 좀 더 놓은 수준의 능력을 갖춘 사람이 된다. 이 둘 사이에는 무슨 차이가 있을까? 공식적으로는 뚜렷하게 차이점이 정의되어 있지는 않다. 필자는 최소한 다음을 잘 이해하고 있는 사람은 개발자로서 프로그래머와의 구분을 가져오는 차이가 있다고 생각한다. 개발 방법론 개발 방법론은 프로젝트 초기에 선택되어야 할 가장 최우선적인 항목의 하나다. 많은 프로젝트에서 Waterfall에 근간을 둔, 정보 공학적인 방법론을 사용한다. 요즘에는 CBD나 XP (eXtreme Programming)이 많은 프로젝트에서 사용된다. 하지만, 아직까지는 CBD의 성공적인 적용이나, XP를 기가 막히게 사용해서 좋은 효과를 얻었다는 얘기를 그다지 많이 듣지 못했다. 필자의 판단으로는 현재 가장 쓸만한 방법론은 UP(Unified Process)며, 현실적인 프로젝트에서는 UP를 간단화 시킨 UP-Lite를 사용하는 것이 좋다고 판단된다. UP는 Rational사(현재는 IBM으로 합병됨)에서 RUP라는 이름으로 널리 알려진 개발 방법론이다. 필자의 판단으로 가장 가슴에 와 닿는 UP의 주장이나 개념은 시스템이나 고객의 requirement는 초기에 결정되지 않는다는 점이며, 이 때문에 많은 workflow들이 칼로 무를 자르듯 뚜렷하게 구분되지 않는다는 것이다. 얼마나 많은 프로젝트에서, “언제 설계가 끝나나요?”, “설계서는 언제 나오나요?” 등의 waterfal

Apache Web Server 1.2 beck exploit 버그의 교훈

Apache web server 1.2 beck exploit 는 Apache Web Server 1.2에 있던 버그라고 합니다. ( http://www.iss.net/security_center/reference/vuln/HTTP_Apache_DOS.htm 참조.) Apache web server에는 / (slash) 가 동시에 여러 개 입력되는 URL이 있는 경우에 이를  이를 1개로 만드는 기능이 있습니다. 예를 들어, /d1///d2////d3/test.html 의 값으로 입력되면, 이를 /d1/d2/d3/test.html로 변환하는 기능입니다. 그런데 프로그램 모듈(no2slash)의 버그 때문에 시스템의 성능을 저하시키는 영향을 미치게 되어, DOS (denial of service) 공격이 용이하게 하는 문제를 안고 있었습니다. 이 프로그램의 원문은 다음과 같습니다. void no2slash(char *name) {   int x, y;   for (x = 0; name[x]; ) {     if (x && (name[x-1] == '/') && (name[x] == '/')) {       for (y = x + 1; name[y-1]; y++)         name[y-1] = name[y];     }     else {       x++;     }   } } 이 프로그램의 시간 복잡도는 2차(quadratic) 식입니다. 즉, ‘/’ 의 개수의 제곱에 비례하는 수행 시간이 증가하는 특성이 나타납니다. 이 특성 때문에, 많은 개수의 ‘/’가 포함된 URL이 주어지면, 이를 처리하느라 CPU의 시간을 다 소모하게 됩니다. 이를 개선한 프로그램은 다음과 같습니다. public void no2slash2(char[] name) {   int n = name.length;   int offset = 0;   for (int i = 1; i < n; i++) {   

true, false, positive, negative – TP/TN/FN/FP

그다지 복잡한 내용도 아니고 몇 번을 보고 외우고 했던 내용이지만 자꾸 헷갈려서 정리를 합니다. 스팸 메일 필터를 예로 들어 보겠습니다. 실제 한통의 메일은 스팸일 수도 있고 아닐 수도 있습니다. 이 한통의 메일을 스팸 필터가 판단을 해서 스팸인지 아닌지를 구분합니다. 그러면 다음과 같이 4가지의 결과가 나올 수 있습니다. 실제로는 스팸 - 스팸이라고 판정: 이 경우를 true positive(TP)라고 합니다. 실제로는 스팸 – 스팸이 아니라고 판정 – 이 경우를 false negative(FN)라고 합니다. 실제로는 스팸 아님 – 스팸이라고 판정 – 이 경우를 false positive(FP)라고 합니다. 실제로는 스팸 아님 – 스팸이 아니라고 판정 – 이 경우를 true negative(TN)라고 합니다. 이를 도표로 정리하면 아래와 같습니다.   스팸이라고 판정 스팸이 아니라고 판정 실제로 스팸 true postivie false negative 실제로 스팸이 아님 false positive true negative

Linux의 date 명령어

UNIX 또는 LINUX 에서 다음과 같은 명령어를 입력하면 $ date 아래처럼 지금의 날짜와 시간이 표시됩니다. 2009. 04. 17. (금) 18:52:15 KST 어제의 날짜를 알고 싶으면, 다음과 같은 옵션들을 주어서 입력하면 됩니다. $ date -d yesterday $ data --date="yesterday" 이 방식이 괜히 직접 작성한다고, 날짜를 빼고, carry되는 거 계산해서 월에서 하나 빼고 하는 방식보다 훨씬 간편하고 정확합니다. 즉, 오늘이 4월 1일이면, 어제는 4월  0일이 아니라, 3월 31이 됩니다. 이 기능은 직접 작성해 본 사람만이 그 노가다의 압박을 이해합니다. 어제가 아닌 며칠 전의 날짜를 알고 싶으면, 예를 들어 100일 전의 날짜를 알고 싶으면 다음과 같은 옵션을 주면 됩니다. $ date -d "-100 days" $ date -d "100 days ago" $ date --date="-100 days" $ date --date="100 days ago" 100일 후의 날짜를 알고 싶으면, $ date -d "+100 days" $ date --date="+100 days" 하지만 다음의 옵션 조합은 에러가 납니다. $ date --date="100 days after" 왜 after를 처리하지 않았을까요? 아마도 자동으로 뒤에 ago가 없으면 뒤(after)의 날짜가 되게끔 되어 있는 스펙이라고 생각됩니다. 장난삼아 다음처럼 옵션을 줍니다. $ date -d "-100 days ago" 이 경우에는 ago는 100일 전을 의미하는데, - (음수) 기호가 붙었으니까, 100일 후가 되어야겠지요. 역시 기대한 결과를 얻습니다. 일(day)이 아니라 월(month)도 옵션으로 가능합니다. 2개월 3일 후의 날짜를 알고

리틀의 법칙 – Little’s law

IT관련 프로젝트를 진행하다 보면 심심치 않게 성능과 용량에 대한 문제를 다루게 됩니다. 성능과 용량 문제는 매우 복잡하고 알아야 할 것이 많은 부분입니다. 그리고 이런 분야는 수요가 그리 많지 않기 때문에 많은 사람들이 크게 관심을 기울이지 않습니다. 이 부분에 대한 가장 기본적인 수식으로 리틀의 법칙 (Little's law)이라는 것이 있습니다. 계산식은 간단하며 다음과 같습니다. n = x * (z + r) 여기서 각 변수의 의미는 다음과 같습니다. n - 동시 상용자 수, x - 시스템이 처리 가능한 용량, 다른 용어로는 throughput이라고 합니다. r - 단위 처리의 응답 시간, z - 각 단위 처리 사이의 간격 (이른바 씽크타임, think time). 이 법칙에 대한 예를 들어보겠습니다. 간단한 성능 테스트를 진행했을 때의 결과가 다음과 같이 나왔다고 가정해보겠습니다. 동시에 1명이 접속하고 think time은 0이고, 꽤 많은 횟수를 테스트할 때 평균 응답 시간이 2초로 측정되었다면 이를 리틀의 법칙 수식에 넣으면 다음과 같이 될 것입니다. 1 user = x * (0 sec + 2 sec) 이 수식을 풀면 x 값은 0.5 (user/sec)가 됩니다. 즉, 1초에 0.5 사용자의 동시 요청을 처리할 수 있는 용량입니다. 잠깐만요… throughput 즉 x 값이 0.5라면 너무 적은 값이 아닌가요? 그렇습니다. 이 테스트의 결과로는 throughput은 0.5가 맞습니다. 단, 최대 throughput은 아닙니다. 동일한 시스템에 대하여 더 테스트를 진행합니다. 그래서 다음과 같은 측정값들을 얻었습니다. 동시에 5명이 접속하고, think time은 0 (그리고 당연히 꽤 많은 횟수를 테스트하고) 일 때, 평균 응답 시간이 2.3초가 나왔다면, 다음과 같이 수식이 나올 것입니다. 5 user = x * (0 sec + 2.3 sec) 이 식을 계산하면 x는 대략 2.17 users/sec 의 값을 갖습니다.

Java의 String 객체의 메모리 사용량

인터넷에서 자료를 찾다가, 우연히 다른 사람의 블로그를 방문하였습니다. 그 블로그에서는 다음의 두 프로그램이 JVM 메모리 사용량 관점에서 볼 때 너무 상이한 결과가 나온다면서 의아해하더군요. Program 1 String str = "0123456789"; List list = new ArrayList(100); long realSize = 0; for (int i = 1; i < 100000000; i++) {   String data = “0123456789” + str;   list.add(data);   realSize += data.getBytes().length   if (i % 10000 == 0)     System.out.println("dataCount=" + i + ",dataSize=" + realSize); } 간단한 이 Java 프로그램을 -Xms256M -Xmx256M의 옵션으로 실행하면, 약 300만개(3,000,000)의 String을 ArrayList에 저장하고 out of memory 에러가 발생합니다. 즉, 256MB 정도의 메모리를 사용하는 Java 프로그램은 문자가 20개인 String 객체를 300만개 정도 만들어서 다룰 수 있습니다. 반면에 다음의 프로그램을 보시죠. Program 2 String str = "0123456789"; List list = new ArrayList(100); long realSize = 0; for (int i = 1; i < 100000000; i++) {   String data = new String("01234567890123456789"); // 요기 한줄만 다릅니다.   list.add(data);   realSize += data.getBytes().length   if (i % 10000 == 0)    System.out.println("d

Priority Queue와 전체 데이터 중 상위 n 개 선택하기

이미지
프로그래밍을 하다보면 가끔은 이런 문제에 직면합니다. 문제는 다음과 같습니다. - 전체 데이터 중에서 상위 100개를 고르는 경우. - 전체 데이터 중에서 100번째 데이터의 값을 알아야 하는 경우. 가장 단순한 답은, 전체 데이터를 정렬(sorting)한 후, 상위 100개를 순서대로 찾으면 됩니다. 전체 데이터 수가 작을 때는 어떤 방법을 써도 별 문제가 없습니다. 문제는 전체 데이터의 갯수가 매우 큰 경우입니다. 대략 1억개 정도라고 가정해 보겠습니다. 정렬에 n x log2(n) 정도의 시간이 걸립니다. 1억 x log2(1억) 정도의 시간이 걸리죠. 대략 27억 (= 1억 x 27) 정도의 시간이 걸리는군요. 다른 방법을 살펴보겠습니다. 어떤 자료 구조(data structure)가 있어서 자동으로 100개의 데이터를 관리해 준다고 가정합니다. 이 자료 구조는 새로운 데이터를 넣으면 100개 안에 해당하는지 아닌지를 판단해서 관리합니다. 그 시간이 얼마나 걸릴지는 모르겠지만, DT라고 하겠습니다. 그럼, 이런 데이터 구조를 이용한다면 시간이 얼마나 걸릴까요? 쉽죠. 1억 x DT입니다. 이런 수치가 나오는 이유는 다음과 같습니다. 1억은 모든 데이터의 갯수입니다. 그러니까, 모든 데이터를 최소한 한번은 봐야 한다는 뜻입니다. DT는 하나의 데이터가 100번째 안에 드느냐 아니냐를 판단하기 위한 시간입니다. 즉, 1억개의 데이터를 다 보면서, 각각이 100번째 안에 드느냐 아니냐를 판단하는 시간이죠. 이제는 DT가 27보다 작냐 크냐만 알면 됩니다. 1. 어레이 (array) 사용 제일 단순한 방법은 그냥 어레이로 100개의 데이터를 관리하는 것입니다. 즉, 100개 크기의 어레이을 만든 후, 데이터가 들어올 때마다, 이 테이터가 100개 안에 들어오는가 아닌가를 판단하는 것이죠. 기존의 100개의 데이터 범위에 들어오면, 그 데이터를 넣고, 가장 작은 데이터를 버리면 됩니다. 안 들어오면, 즉 100등

ebook의 장단점

최근에 몇권의 ebook을 읽다보니, 다음과 같은 장단점이 느껴집니다. 장점 1. 사고 싶을 때 주말이나 야간을 가리기 않고 즉시 구매해서 볼 수가 있다. 2. 종이책보다 상대적으로 가격이 저렴하다. 3. 한번의 구매로 여러 device에서 구독이 가능하다. Purchase once, read anywhere. 4. 한번의 구매로 (통상) 평생 소장이 가능하다. 5. 물리적인 특성에 따른 제약이 없다. 무거움, 분실, 낡음, 찢어짐 등등이 없다.     이에 따라서, 책꽂이가 작어도 버릴 필요가 없으며, 보관에 공간 제약이 없다. 6. 책내에서의 검색, 마킹 및 노트가 자유롭다. 단점 1. 종이책보다는 읽는 맛이 부족하다. 2. 집중도와 이해도가 종이책보다 떨어진다.     니콜라스 카의 '생각하지 않는 사람들'이란 책에서 지적한 점이다. 3. 남들이 볼 때는 게임이나 웹서핑하고 있는 줄 안다. 4. 남들에게 빌려줄 수가 없다.    따라서, 남들에게 한번 읽어보라고 권유하기도 어렵다. 5. 시력에 좋지 않다. (최근에 현실적으로 드러나는 문제점) 메뉴얼이나 정보를 습득하기 위한 목적의 책이라면 단연코 ebook이 좋겠지만, 뭔가 아날로그적인 감성이 필요한 종류의 책이라면 종이책이 더 나을 것 같습니다. --