The Last Mind

Captain's Log

Monthly Archives: January 2007

Lizardlings are Stupid

31 January 2007 by Joseph Jang

Neverwinter Nights 2의 주인공은 West Habor에 살고 있는 촉망받는 젊은이인데, 어느날 갑자기 알 수 없는 이유로 West Habor가 습격당하는 것으로 Act I은 시작됩니다. 습격자들을 물리치는 과정에서 주인공은 그들이 누군가에 의해 조종받고 있으며, 어떤 물건을 찾고 있다는 것을 알게됩니다. 주인공의 양아버지는 그 물건이 바로 자기가 예전에 숨겨둔 Silver Shard 때문일 것이라며 마을을 보호하기 위해서는 그 물건을 Neverwinter 시로 가져가야한다고 합니다. 주인공은 아버지의 명에 따라 Silver Shard를 찾으러 가는데, 그곳은 많은 수의 Lizardlings이 차지하고 있었습니다.

치르고 있던 의식을 방해받은 Lizardlings는 주인공 파티에게 적대적인 태도를 취합니다.

주인공은 여기에 대한 변명을 해야하는데, 제가 만든 주인공의 Charisma attribute가 높아서 그런지 몰라도 Diplomacy와 Bluff가 선택지로 뜹니다.

    1. [Diplomacy] 이 곳이 우리 차지였을 때, 우리 부족이 뭔가를 여기에 두고 갔소.
    2. [Bluff] 석신이 당신들의 기도를 듣고 나를 보낸거요.
    3. 문을 열어 준 것 고맙지만, 이제 죽어줘야겠어.
    4. 막 갈려던 참이었다구요.

일단 1번 답을 선택해봅시다.

성공입니다. 그런데, 자기네 땅에 들어온 건 이해하겠는데, 의식을 방해한 건 이해못하겠답니다. 교주(?)라서 그런지 몰라도 대단히 똑똑한 Lizardling이군요. 여기에 대한 답변으로 4번 선택지에 Lie가 뜨네요.

[Lie] 당신들이 여기에 오기 전부터 우리는 석신을 섬겨왔소. 석신께서는 우리들이 서로 돕기를 원할거요.

주인공의 Alignment가 Chaotic Good니까 Lie를 선택하는 것이 합당해보입니다.

역시 성공했습니다.

그렇다면, 애초에 Bluff를 선택했다면 어떨까요? 다음과 같습니다.

난 석신의 화신이다. 너희들은 나를 두려워하라!

라고 하니까 그대로 넘어가네요.

오늘의 교훈: Lizardling들은 멍청하다.

아래는 Silver Shard를 상자에서 꺼내고 있는 주인공 Elenella Lane (제가 만든 캐릭터)의 모습입니다.

Comments | Categories: Game

Someone who doesn’t judge me

30 January 2007 by Joseph Jang

Greg: “I consider myself to be pretty open-minded. I find other people’s predilections very intriguing. What do you like? What gets your juices flowing?”
Grissom: “Someone who doesn’t judge me.”

CSI: Crime Scene Investigation, Season 5th

Comments Off |

모든 것은 마이크로소프트 탓

26 January 2007 by Joseph Jang

이런 ‘시장 혼란’은 결국 윈도의 독점력에 따른 결과다. 다른 대안이 없는 만큼 윈도 비스타에 맞게 서비스 프로그램을 고쳐야 하는 것이다. 정통부도 ‘꼼꼼히 확인해 구매하라’는 이용자 안내에 그칠 뿐, 뽀족한 대책을 내놓지 못하고 있다.

비스타 출시에 따른 이런 혼란은 한국이 유독 심한 것으로 알려졌다. 액티브-엑스의 사용이 보편화되지 않았고 인터넷 연결이 우리나라만큼 원활하지 않기 때문이다. 익명을 요청한 정보통신부 관계자는 “지난해 3분기부터 엠에스 쪽과 공동작업을 했는데, 우리나라의 경우 응용프로그램이 발달해 손볼 대목이 많았음에도 엠에스가 기술자료 공개를 늦게 하는 바람에 이런 일이 벌어졌다”고 말했다.윈도 비스타 혼란…지금 깔면 손해, 한겨레

그렇습니다. 외국은 인터넷 연결과 같은 인프라도 미비할 뿐만 아니라, 소프트웨어가 별로 발달하지 않아서 ActiveX라는 뛰어난 기술도 아직 보편화되지 않았답니다. 게다가 마이크로소프트는 인터넷과 소프트웨어가 우월한 대한민국의 상황을 따라오지 못하고 늑장대처를 하는 후진국 기업의 행태를 보여주고 있습니다.

Comments |

Next Release of IBM Lotus Notes and Domino

24 January 2007 by Joseph Jang

IBM also said the long-awaited next release of IBM Lotus Notes and Domino, known until now as “Hannover,” will enter the public beta phase of its testing in February and should be generally available mid-year. (From IBM Expands Line of Collaboration Software Tools)

IBM의 그룹웨어 솔루션인 Lotus Notes와 Domino의 차기버전 Hannover가 나온단다. Lotus Notes의 Usability는 그야말로 최악이다. (Lotus Notes Sucks) 그냥 출시안하면 안되겠니?

Comments Off |

Detecting Duplicated Code in Eclipse

23 January 2007 by Joseph Jang

중복된 코드(Duplciated Code)는 Long Method와 함께 Bad Smell의 대표적인 사례 중 하나다. 사람이 중복된 코드를 찾기 위해서는 모든 코드를 봐야하지만, 컴퓨터는 이를 손쉽게 할 수 있다. 컴퓨터가 쉽게 할 수 있는 일은 컴퓨터에게 맡기자.

Eclipse에서 중복된 코드를 탐지해주는 플러그인은 두가지가 있다. 예전에 한번 언급했던 PMD의 부가적인 기능인 CPD(Copy/Paste Detector)를 사용하거나 SDD (프로젝트 사이트)를 사용할 수 있다.

두 플러그인 모두 중복된 코드를 탐지하는 기능 자체는 잘 동작하나, 완성도가 좀 부족해보인다. CPD의 경우에는 중복된 코드에 대한 리포트를 텍스트 파일로 출력해주고, SDD는 Eclipse의 View를 사용해 바로바로 중복된 코드로 찾아갈 수 있도록 되어있으나, 라인 단위가 아닌 문자 단위라서 조금 불편하다. 두 플러그인 모두 하나의 프로젝트 내에서만 중복 코드 탐지가 가능하기 때문에, 여러 프로젝트 간에 코드를 Copy-and-Paste하는 경우를 탐지할 수 없다.

재미있게도 SDD는 정일영이라는 고려대 컴퓨터교육과 분이 만드셨는데, 이걸로 OOPSLA 2005 포스터 세션에 나가신 모양이다. 왠지 얼굴을 알고 있는 분이라는 생각이…

덧붙여, 코드 분석에 관련된 Eclipse 플러그인에 관심이 많다면 Automation for the people: Improving code with Eclipse plugins 이라는 기사가 도움이 될 것이다. Test coverage를 위한 Coverclipse나 Dependency analysis를 위한 JDepend와 같은 플러그인들은 아직 시도해보지 못했다.

Comments Off | Categories: Software Development

Metrics

19 January 2007 by Joseph Jang

http://metrics.sourceforge.net/

자신의 코드를 리팩토링하는 시점은 여러가지(예를 들면, 새 기능을 추가할 때)가 될 수 있겠지만, 이미 관리하기 힘들 정도로 난잡해진 코드를 리팩토링하기 시작해야할 때는 ‘무엇부터 리팩토링할 것인가‘를 결정해야한다. Martin Fowler는 그의 책 Refactoring에서 리팩토링을 해야하는 나쁜 코드의 증상을 ‘Bad Smell‘이라고 한다. 리팩토링의 우선 순위가 높은 코드는 아마 이러한 ‘Bad Smell’이 강하게 나는 코드일 것이다. ‘Bad Smell’을 맡는 방법은 눈으로 모든 코드를 직접 보는 방법도 있겠지만, 팀 개발을 할 경우, 매일 매일 commit되는 코드를 모두 보기란 쉽지 않은 일이다. 기계가 이 일을 대신해 줄 수는 없을까? Metrics는 바로 그러한 일을 해주는 Eclipse 플러그인으로, 코드의 질을 몇가지 유용한 기준들에 따라 수치화해서 보여주고, 정해진 수준을 넘어설 경우 경고도 해준다.

Metrics가 측정해주는 기준들에는 여러가지가 있지만, 일단 어떤 경우에나 유효하다고 생각되는 기준인 ‘Method Lines of Code‘를 채택해서 리팩토링 작업에 적용해보고 있다. ‘Method Lines of Code’는 말 그대로 메서드의 길이인데, 일반적으로 ‘Long Method‘는 이미 나쁜 코드이거나 나쁜 코드로 발전할 가능성이 상당히 높을 뿐더러, OOP에서는 대략 상식을 벗어나는 코드에 해당한다. 디폴트로 Maximum 값이 설정되어있지 않으므로, Preference에서 일단 이 Maximum 값을 가장 보수적인 수치인 100으로 설정(즉, 100라인 이상의 메서드를 경고)해서 리팩토링 대상을 찾고 있다. 현재 프로젝트에서 1등은 350라인이었다는 놀라운 사실도 발견했다. (다행히도, 내가 짠 코드는 아니었다.) 점차 이 기준을 강화해서 대략 50라인 정도로 만들어야 하지 않을까 싶다.

‘Method Lines of Code’를 해결하고 나면, McCabe Cyclomatic Complexity라는 기준을 적용해보려고 생각하고 있는데, 이 기준은 코드 상에서 얼마나 많은 분기가 존재하는가를 나타내는 것이다. 경험 있는 개발자라면 뼈저리게 느끼듯이, 분기가 많다면 코드는 이해하기 힘들다. 프로그래머가 프로그램을 이해하기 위해서는 프로그램의 특정 부분에서 존재할 수 있는 프로세스의 모든 상태들을 알고 있어야하기 때문이다. (디버깅 세션을 상상해보면 이를 이해하기 쉽다.) OO 프로그래밍의 중요한 강점 중의 하나가 바로 이러한 분기들을 객체의 polymorphism으로 해결하는 것이다. 이는 Procedural 프로그래밍에서도 마찬가지로, 경험 있는 C 프로그래머라면, function pointer를 이용해서 polymorphic behavior를 구현해본 경험이 많을 것이다.

최근에 강문식 군을 통해, 자신들의 프로덕트의 코드 품질을 공개하는 Open Quality (참여하고 있는 프로젝트들의 품질 데이터)라는 개념을 접할 수 있었고 매우 흥미로웠다. 이 곳을 통해 서비스를 받는 것도 가능한 것 같아 보이지만, Metrics의 기능을 Ant task를 사용해서 접근할 수 있기 때문에, 이를 Daily Build에 적용해서, 일단 코드의 품질을 실시간으로 팀내 정도에서 공유해보면 어떨까 생각하고 있는 중이다. 리팩토링을 통한 품질의 개선 정도나, 새 기능의 추가에 따른 품질의 저하 정도 등이 관찰 가능하게 될 것이고, 어쩌면 품질에 대한 다른 접근 방식이 가능하게 될 지도 모른다.

Comments Off | Categories: Software Development

Jolt Awards Finalists

17 January 2007 by Joseph Jang

지난 15일에 졸트상의 후보들이 발표되었습니다. 전 Agile Software Development에 한표입니다.

http://www.joltawards.com/2007/

Books (Practical/General Developer Interest)

Agile Software Development: The Cooperative Game (Addison-Wesley) by Alistair Cockburn
Catastrophe Disentanglement (Addison-Wesley) by E. M. Bennatan
Eric Sink on the Business of Software (Apress) by Eric Sink
Practices of an Agile Developer (Pragmatic Bookshelf) by Venkat Subramaniam and Andy Hunt
Software Creativity 2.0 (DeveloperDotStar) by Robert L. Glass
Software Estimation: Demystifying the Black Art (Microsoft Press) by Steve McConnell
Weinberg on Writing: The Fieldstone Method (Dorset House) by Gerald M. Weinberg

Books (Technical)

Code Quality (Addison-Wesley) by Diomidis Spinellis
How to Break Web Software (Addison-Wesley) by M. Andrews, J. Whittaker
Java Concurrency in Practice (Addison-Wesley) by Brian Goetz et al
Rails Recipes (Pragmatic Bookshelf) by Chad Fowler
Refactoring Databases (Addison-Wesley) by Scott W. Ambler and P. J. Sadalage
Head First Object-Oriented Analysis and Design (O’Reilly) by B. McLaughlin, G. Pollice and D. West
Ruby Cookbook (O’Reilly) by Lucas Carlson and Leonard Richardson
CSS: The Missing Manual (O’Reilly) by David Sawyer McFarland

Comments Off | Categories: Software Development

StandardAnalyzer in Lucene, and Korean

16 January 2007 by Joseph Jang

Lucene에서 Analyzer의 역할은 Field의 텍스트를 TokenStream 즉, 토큰들의 스트림으로 만들어주는 역할입니다. 이 역할을 하는 abstract 메서드가 바로 Analyzer.tokenStream() 메서드인데, signature는 다음과 같습니다.

public abstract TokenStream tokenStream(String fieldName, Reader reader);

Lucene이 제공하는 Analyzer들에서 이 메서드의 구현은 하나의 Tokenizer와 다수의 TokenFilter들을 사용합니다. TokenizerField의 텍스트를 토큰들로 만들어주고, 이 토큰들이 TokenFilter들에 의해 변형되거나 걸러집니다. StandardAnalyzer.tokenStream() 메서드의 구현은 다음과 같습니다.

public TokenStream tokenStream(String fieldName, Reader reader) {

TokenStream result = new StandardTokenizer(reader);
result = new StandardFilter(result);
result = new LowerCaseFilter(result);
result = new StopFilter(result, stopSet);
return result;

}

일단 TokenFilter들에 대해서 설명하면, StandardFilter는 영어에서 소유격을 나타내는 apostrophe 또는 apostrophe s를 제거해주거나 acronym에서 period(.)를 제거해주는 역할을 합니다. LowerCaseFilter는 이름이 의미하듯이 토큰들을 소문자로 만들어주는 TokenFilter고, StopFilter는 지정된 stop word들을 토큰에서 걸러내는 역할을 합니다. StandardAnalyzer가 지정하는 stop word들은 StopAnalyzer.ENGLISH_STOP_WORDS로, 영어에서의 관사나 전치사, 대명사에 해당하는 단어들입니다.

결국 StandardAnalyzer의 한국어 처리에서 중요한 것은 바로 StandardTokenizer인데, 일종의 parser generator에서 생성된 것으로 보입니다. Lucene 소스에서 lucene-2.0.0/src/java/org/apache/lucene/analysis/standard/StandardTokenizer.jj를 보면, 토큰 정의들을 볼 수 있는데, 한국어와 관련해서 다음과 같은 부분이 있습니다.

// basic word: a sequence of digits & letters
<ALPHANUM: (<LETTER>|<DIGIT>|<KOREAN>)+ >

<중략 />

| < CJ: // Chinese, Japanese
[
"\u3040"-"\u318f",
"\u3300"-"\u337f",
"\u3400"-"\u3d2d",
"\u4e00"-"\u9fff",
"\uf900"-"\ufaff"
]
>

| < KOREAN: // Korean
[
"\uac00"-"\ud7af"
]
>

이것을 보면 한국어 문자들을 유니코드 범위로 표현하고, ALPHANUM이라는 토큰이 한국어 문자를 포함하도록 처리하고 있는데, 따라서, StandardAnalyzer를 사용하면, “911사태”, “Bush대통령”과 같은 것들이 하나의 토큰으로 처리됨을 알 수 있습니다. 중국어와 일본어 문자들은 CJ 토큰으로 따로 분리해놓은 반면 KOREAN은 왜 ALPHANUM으로 들어갔는지는 모르겠지만, 궁극적으로는 모든 언어의 문자들이 ALPHANUM에 들어가는 것이 정확하겠죠.

이렇게 해서, Lucene 2.0의 StandardAnalyzer에서 한국어 문자들로 이루어진 단어들이 제대로 인덱싱된다는 것은 알았지만, 이들을 이용해서 잘 검색할 수 있느냐는 다른 문제입니다. Analyzer.tokenStream() 메서드에서 돌려준 TokenStream에 담긴 토큰들을 인덱스에 그대로 저장하기 때문에, (이들을 다른 식으로 가공하기 위한 별다른 레이어를 발견하지 못했습니다.) 쿼리의 토큰들이 문서의 토큰들과 정확히 match되는 문서만 검색 결과에 포함됩니다. 즉, “Bush대통령”이라는 토큰으로 인덱스에 들어간다면, “Bush”나 “대통령”, “대통” 등으로는 이 토큰이 들어간 Document를 검색할 수 없습니다.

이 문제를 해결하기 위해서는, n-gram 분석이나 형태소 분석을 통해 토큰들을 적절하게 분리한 후, 인덱싱해야할 것입니다. lucene-2.0.0/contrib/analyzers/src/java/org/apache/lucene/analysis/cjk/에 있는 CJKAnalyzerCJKTokenizer2문자 단위로 토큰들을 생성하는 극히 단순한 Bigram 분석을 통해 이 문제를 해결하고 있는 것 같습니다. 이 경우의 문제점은 한국어에 존재하는 조사나 용언 어미등이 들어가는 토큰들을 전혀 배제하지 못하는 것인데, 검색의 품질을 상당히 낮출 가능성이 있습니다.

홍태희님은 루씬과 한글이라는 페이지(via 루씬에 대한 한국개발자의 고민들)에서 이 문제를 조사에 해당하는 부분을 토큰에서 잘라내는 TokenFilter를 도입해서 해결하고 계시긴 하지만, 조사에 해당하는 문자로 끝나는 단어들을 검색하지 못하는 문제가 있습니다.

제대로 된 오픈소스 한국어 Analyzer의 수요가 많음에도 불구하고 없는 것이 아쉽습니다. 짧은 생각으로는 단순한 휴리스틱으로는 힘들 것 같고, 충분히 많은 데이터를 이용한 분석이 필요할 듯 한데, 아무래도 오픈소스 활동에 전념하기 힘든 개인의 수준에서는 힘들지 않을까 싶군요. 좀 더 조사해 봐야겠습니다.

Comments | Categories: Uncategorized

Lucene: First Impression

15 January 2007 by Joseph Jang

Lucene 또는 Lucene Java는 매우 유명한 오픈 소스 검색 엔진 소프트웨어입니다. Lucene은 Apache Lucene 프로젝트에 속해있는데, 이 프로젝트는 Lucene 외에도 NutchHadoop 등을 포함하는 Apache의 검색 소프트웨어 프로젝트입니다.

팀에서 웹크롤한 결과의 질을 가시적으로 만들기 위한 방법의 하나로 Lucene을 사용해보기로 했습니다. Lucene이 사용하기 쉽다는 평은 처로군으로부터 자주 들었지만, 이 정도 일 줄은 몰랐습니다. 팀이 가지고 있는 데이터베이스와 연동해서 콘솔을 통해 검색 가능하게 만드는데, 한시간 밖에 안걸렸습니다. Lucene에 대한 사전지식은 거의 없었다고 봐도 무방합니다. Lucene을 사용하기 위해 참고한 것은 Lucene 소스 코드 내에 들어있는 데모와 데모를 간단하게 설명하고 있는 문서 뿐이었습니다. Lucene에 관한 유일한 책인 ‘루씬 인 액션‘을 살짝 보긴 했으나 책에 등장하는 코드들이 out-of-date 더군요. Lucene을 연동하는 코드를 짜는 데에는 별로 도움이 안되었습니다.

1시간 동안 만든 것은 데모의 코드를 Copy and Paste하면서 만든 Indexer 프로그램과 Searcher 프로그램인데, 각각 인덱싱을 수행하는 프로그램과 생성된 인덱스로부터 검색을 수행하는 프로그램입니다.

Indexer 코드의 중요한 부분만을 보자면 대충 다음과 같습니다.

IndexWriter writer = new IndexWriter(INDEX_DIR, new StandardAnalyzer(), true);

// make lucene document
Document doc = new Document();
doc.add(new Field(“url”, uri, Store.YES, Index.UN_TOKENIZED));
doc.add(new Field(“title”, title, Store.YES, Index.TOKENIZED));
doc.add(new Field(“content”, cpmtemt, Store.YES, Index.TOKENIZED));

// add it to IndexWriter
writer.addDocument(doc);

writer.optimize();
writer.close();

간단히 설명하면, IndexWriter는 인덱스를 생성하는 역할을 하고, 인덱스의 단위는 Document입니다. Document는 복수의 Field를 가질 수 있고, Field 별로 tokenize할 것인가, 인덱스에 Field 내용을 저장할 것인가를 지정할 수 있습니다. Analyzer가 Field를 tokenize하는 역할을 하는데, IndexWriter에 명시한 것 외에 Field 별로 Analyzer를 지정할 수 있습니다.

디자인이 도메인을 그대로 반영하고 있고, 단순하면서도 확장성이 높은, 좋은 API입니다.

Searcher 코드도 한번 들여다 보죠.

IndexReader reader = IndexReader.open(“index”);
Searcher searcher = new IndexSearcher(reader);
Analyzer analyzer = new StandardAnalyzer();

QueryParser parser = new QueryParser(“content”, analyzer);
Query query = parser.parse(queryString);

Hits hits = searcher.search(query);

for (int i = 0; i < hits.length(); i++) {

Document doc = hits.doc(i);
String urlString = doc.get(“url”);
String title = doc.get(“title”);
String content = doc.get(“content”);
// …

}

역시 마찬가지로 코드만으로도 이해하기 쉽습니다. 별로 설명할 것이 없네요.

인덱싱 하는데에는 시간이 좀 걸리지만, 한번 인덱싱하고난 후에는 검색 속도는 대단히 빠릅니다. 10만개 정도까지밖에 안해봐서 실제 크기의 데이터에서는 어떨런지는 모르겠습니다.

한편, 한글 관련한 Analyzer 이슈에 대해서는 아직 잘 모르겠습니다만, 한글 검색도 그럭저럭 되는 것 같군요. 좀 더 자세히 알아봐야할 것 같습니다.

현재의 검색 솔루션이 맘에 안든다면, 엔터프라이즈급의 간단한 검색 솔루션으로는 부담없이 연동해서 쓸 수 있는 수준인 것 같습니다.

지금 구글 검색해보니, 좀 더 좋은 튜터리얼 들이 있군요. 참고하세요.

Comments | Categories: Software Development

How To Code

12 January 2007 by Joseph Jang

‘How To Code’는 팀 내에서 발표할까 생각했다가 취소한 발표자료입니다. 내용은 소프트웨어 개발에서 프로그래머가 지켜야하는, 또는 지키도록 기대되는 기본적인 원칙들 입니다. (빠진 것들도 많겠지만, 생각나는 중요한 것들만 적었습니다.)

발표 자료에 관해 잠시 언급하자면, 이 발표 자료만으로 발표하는 것은 졸린 설교가 될 가능성이 높기 때문에, 충분한 예들이 있어야 합니다. 가능하다면, 팀에서 쓴 코드를 직접 사용하는 것도 괜찮다고 생각이 됩니다.

최근에, 팀 내에서 잘 지켜지지 않는 개발 원칙들을 어떻게 바른 방향으로 유도할 것인가에 관해서 대단히 관심이 많아졌는데, 이런 원칙들만을 나열하는 것은 ‘당신이 잘못 했으니까 고치라’라는 식으로 들릴 가능성이 높고, 그렇다면 절대 변화는 일어나지 않을 것이라는 생각이 듭니다.

다른 사람들을 변화시키려면, 원칙 이전의 가치에 대한 공감대가 필요한데, 우선 그 공감대가 형성되어있는가, 또는 어떻게 형성될 수 있는가를 따져야할 것 같습니다. 공감대를 어떻게 형성할 수 있는가에 대해서는, 이러한 원칙들이 실제로 적용되는 경우를 보여주면서 그것이 좋다는 것을 ‘느낄’ 수 있도록 해주는 것이 가장 좋은 방법인 것 같습니다. 이를 위한 실제적인 방법으로 ‘코드 리뷰’를 생각 중입니다만… 여러모로 아직 고민 중입니다.

Comments Off | Categories: Uncategorized

← Older posts