월요일, 7월 26, 2010

잘못된 기억이 창의의 원동력 ?!

특정한 알고리즘을 찾으며 밤을 뒤척이다가 출근길에 문득 엉뚱한 생각이 들었다.

사람의 뇌는 특정한 느낌을 키로 해서 관련 기억들을 찾아준다. 아마도 어떤 상황에서 느낀 느낌을 상황과 함께 저장하는 구조가 아닐까 싶다.

어떤 친구는 패턴 매칭과도 유사하다고 얘길 하던데 키가 되는 패턴이란 것이 그러한 순간적인 감성이 아닐까 싶다. 우리가 흔히 얘기하는 감정보다는 매우 세분화된 느낌일 것이다.

요즘따라 옛 기억들은 찾은 후에 곰곰히 앞뒤를 연결해보면 시간이나 인과 관계가 안 맞는 것들이 많다. 나이가 들어 기억력이 쇠퇴했거나, 가끔씩 과도한 음주로 인한 뇌세포 소실이 원인이 아닐까 싶기도 한데 왜 이 기억들이 떠올랐을까 생각해보면 말로 표현하기 어려운 어떤 느낌들이 공통성이 있었던 것 같다.

창의는 논리적 연역에서 출발한다는 주장이 있다. 즉, 창의는 논리 체계에 따라 정보를 재구축하는 데서 출발한다는 주장이다. 개인적으로는 매우 동의하는 편이다.
하지만, 수학적 귀납법의 경우 결과적으로 증명은 이루어지지만, 그 증명은 연역의 방법이 아니라, 어떤 선험적 직관에 의한 귀납으로 증명하기 때문에 이러한 사고 과정도 중요한 창의의 하나로 본다면 연역적 논리 전개만으로는 창의를 이해할 수는 없다.

선험적 직관이란 선행 학습에 기반한 개괄적 느낌을 뜻한다. 특정한 상황의 알고리즘을 찾는 일은 그 상황을 아무리 쥐어짜도 해결되지 않는 경우가 많다. 이때 발생하는 논리적 탈출구는 직접적으로는 연관이 없는 다른 관련 경험 지식을 적용함으로써 찾는 경우가 많이 있다.

뇌가 유사한 느낌으로 저장해둔, 직접적인 연관성이 없는 지식과 기억들을 상황에 대입했을 때, 직접적인 해결은 아니지만, 새로운 해결의 실마리를 찾을 경우가 종종 발생한다.
이것이 바로 위대한 발명, 대단한 창의가 아닐까 생각해본다.

뇌에 저장된 기억들이 정확하지 않음을 슬퍼하지 말자. 이런 잘못된 기억, 잘못된 직관들을 상황 대입을 통해 창의를 이루는 또다른 방법론으로 활용할 수 있지 않을까?

정확한 은유에 기반한 연역적 논리 전개를 통한 새로운 속성과 법칙성의 발견이 하나의 방법이라면, 잘못된 기억과 직관을 상황 대입하여 새로운 해결의 실마리를 찾는 것이 또다른 창의의 방법이 아닐까.

문득 지하철 속에서 알고리즘의 상황을 정리하다가 떠올린 생각.

토요일, 7월 17, 2010

전략과 전술에 대한 단상

1998~1999 시즌 남자농구 기아팀 감독은 박인규 씨였다.

코치에서 처음 감독으로 데뷔한 해, 포스트 시즌에서 기아는 당시 허재 선수가 노장으로 뛰고 있었다. 문득 이 기억이 가끔 나는 것은 기아가 4쿼터에서 4,5분 남겨놓고 밀리고 있는 시점에서 부른 작전 타임아웃 때문이다. 보통 신선우 씨 같은 지략가 감독들은 매우 많은 작전을 지시한다. 선수들은 그 작전에 따라 자신의 위치를 변경하면서 훈련한 데로 움직이기 때문에 부담감도 줄어들고, 또 훈련한 데로 움직일 수 있는 것이다.
그런데 박 감독은 타임아웃 시간 동안 단 한 가지 말만 했다.
특유의 어눌한 말투로 느릿느릿하게

"이럴 때일수록 수비가 중요해"

그러자 (아마도 타임아웃 시간이 남아도니까...), 외국인 기술코치 같은 사람이 영어로 뭐라고 떠들고 선수들은 선수들대로 자기들끼리 떠들고 허재 선수는 외국인 코치를 쏘아보고...
TV 중계를 보고 있었는데 매우 충격적이었다. 결국 기아는 그후 4,5분 동안 급격하게 무너지고 말았다.

박인규 씨는 첫 사령탑에 올라 좋은 경험을 쌓았을 것이다. 그후 삼성생명 여자농구팀 감독을 맡아 우승도 한 것으로 알고 있다.

다만, 이 기억이 자꾸 나는 것은 지도자가 전략과 전술이 없으면 해볼 수 있는 것이 없다는 것이다. 그 당시에는 정말 충격이었다. 정말 감독이란 사람이 그저 위치만 차지하고 팀을 화학적으로 이끌지는 못하고 있구나 하는 생각.

요즘따라 이 기억이 자꾸 연상되는 것은 모 기업의 어려움은 아무런 전략과 전술이 없는 경영의 문제는 아니었을까 하는 것이다.

"어려울 때일수록 더 공격적으로 투자"

뒤지고 있던 경기를 막판에 몰아부쳐 거의 따라간 상태에서 역전골을 먹었을 때, "이럴 때일수록 수비가 중요"하다고 하고, 아무런 전술적 detail 을 전달하지 못하는 초보 감독의 한계에서, 냉철한 현실 인식 위에서 전술적 공격과 후퇴를 배치하는 것이 아니라 공허한 구호만 남발하고 이에 따라 모든 기업 운영을 전략 구호와 즉흥성에 의존하는 서글픈 오류를 본다.

오래된 기억이라 상세한 것은 잘못 연상된 것도 있을 것 같지만 당시 기아는 팀 전력만으로는 상대가 너무 강하였다. 다만 끝까지 제대로 붙어보지 못하고 스스로 막판에 무너진 듯한 게 아쉬움으로 남았었다.
박인규 감독은 그후 여자 감독으로 우승도 차지하였기에 재기에 성공한 것으로 보이지만 구체적 전술을 적시에 구사하는 감독이 되었는지는 알 길이 없다.
실패를 정확하게 인식하고 보완한다면 무엇이든 가능할 것이다. 다만 그 현실 인식 능력이 못 미더울 뿐이다. 아니라면 decision을 철저하게 다른 사람이나 조직에 위임을 해야 한다.

토요일, 7월 03, 2010

Vision Statement를 단순하고 분명하게 개발하자

많은 소프트웨어 기업들이 명멸한다. 하지만, 기동성이 필요한 소프트웨어의 경우 비전이 분명할수록 예측 가능하고, 또 사업 영역 또한 결정이 쉬운 경향이 있다.

물론 비전에는 통찰과 철학, 신념이 필요하다.
하루 아침에 만들어지는 게 아니며, 또 불변의 문장일 필요도 없다.

성공을 향해 달리는 도전적인 조직에서는 방향을 분명하게 설정하지 않으면 길을 잃기 쉬우므로 명료한 기업의 비전이 필요하다.

지난 얘기지만, 오러클에 인수된 Sun Mircosystems 사의 비전 문장은 "Network is Computer" 였다.

어떤 비평가는 Sun사의 몰락은 자신의 비전에 충실하지 못했기 때문이라고 지적했다. 오히려 Google이 Sun사의 비전을 더 충실히 이행한 것 아니냐는 반문을 했다.

Sun사의 경영 방향은 컴퓨터는 컴퓨터였고, 네트웍이 컴퓨터를 대체할 것이라고 믿지 못했다.
통찰력이 뒷받쳐주지 못했고, 비전에 대한 확신이 부족했다.

오히려 Google의 비전은 "모든 것은 웹을 통한다"였다. 웹 즉, 인터넷이 컴퓨터였고, 컴퓨팅 뿐만 아니라 사람의 생활과 문화도 모두 웹을 통하도록 유도하고 있다.
수익 모델 역시 웹을 통하는 것이 바로 Google의 수익이 되도록 하고 있다.

예전에 모질라와 넷스케이프를 개발했던 Jamie Zawinski 는 메일 프로그램에 대해 다음과 같은 비전을 가지고 있었다.


"모든 프로그램은 메일을 읽을 수 있을 때까지 확장되고 싶어한다. 메일을 읽을 수 없는 프로그램들은 메일을 읽을 수 있는 프로그램에 의해 대체되고 말 것이다. Every program attempts to expand until it can read mail. Those programs which cannot so expand are replaced by ones which can."



약간 생뚱맞게 느껴지겠지만, Jamie 는 메일을 통한 collaboration의 중요성을 지적한 것이다.
모든 회사가 차세대 컴퓨팅을 이끌 필요는 없다. 이러한 명확한 비전 문장이 있다면 회사의 할 일은 좀더 분명해질 수 있다.
예를 들어 Google 은 GMail 을 웹 기반으로 개발하고, 또 GMail에 Buzz를 붙였다. 다른 웹 application도 GMail과 연동을 하겠지만.. 만약 메일을 collaboration을 위한 핵심 플랫폼으로 인식한다면 이에 맞는 application platform으로서의 GMail을 생각할 것이다.
GMail이 이런 비전을 가지고 있다거나 이것이 옳다는 것이 아니므로 오해하지 말기를..

정확하고 가치있는 비전은 중장기적으로 기업의 갈 방향을 알려주고 또 직원들을 하나로 묶어준다. 비전의 진성성과 이에 대한 충실성이 문제가 될 뿐.


Google은 웹으로 할 수 있는 모든 것을 Google을 통해서 하도록 한다. 그것이 메일이든 메신저든 오피스든, 지리 정보든, 상관 없이...


Facebook 은 세상을 좀더 열린 세상이 되도록 바꾸는 것이 목표라고 한다. 
(from http://mashable.com/2010/06/22/what-facebook-gets-right/)

당신이 몸담고 있는 기업의 비전은 무엇인가. 또, 당신의 비전은 무엇인가? 이 비전은 미래를 준비하고 있고, 세상의 변화와 부합하는가, 혹은 오래도록 변하지 않을 가치에 기반하고 있는가?
트렌드에 뒤늦게 쫓아가려고만 하지는 않는가?

마냥 스스로 통찰력이 부족하다고만 할 일이 아니다. 비전을 만들고 다듬고 개발하고 이에 따라 결정하고 행동해야 할 때이다.

Java Distributed GC and -XX:+DisableExplicitGC option

자바 프로그램에서 OutOfMemoryError 는 흔하게 발생하지만, 그 원인이 무척 다양하기 때문에 단순하게 메모리 부족으로 판단해서는 안된다.

에러 메시지에서 구분할 수 있는 세 가지는 1. heap memory가 부족한 경우, 2. perm area memory가 부족한 경우, 3. 새로운 thread를 생성할 수 없는 경우이다.

heap memory가 부족한 것은 JVM에 지정한 최대 heap 메모리 크기보다 더 큰 메모리 영역을 사용하려고 시도했기 때문인데 application이 memory leak을 발생시켜 사용 메모리가 점점 증가하는 경우라면 application의 leak을 해결하든지, 주기적으로 JVM을 재구동하든지 해야 한다. 그것이 아니라 순간적으로 큰 메모리를 사용할 가능성이 높은 applicaiton이라면 JVM의 최대 heap 크기를 늘려줘야 할 것이다.

이와 달리 perm area 부족의 경우는 조금 다른데 Sun(지금은 Oracle)의 HotSpot JVM에서는 permanent area 에 String 상수 풀이나 define된 클래스 정보들을 두고 있다.

보통의 경우 상수 풀이나 클래스 정보는 한번 load되면 unload할 일이 없지만, application의 특성에 따라 pluggable module 이 필요한 경우 이를 구현하기 위해 동적으로 ClassLoader를 생성하고 삭제하는 방법을 흔히 사용하는데, 이때 클래스 정보들이 적절히 unload되지 않으면 perm area에서도 memory leak이 생기게 된다.
즉, perm area에서의 memory leak은 ClassLoader 객체가 제대로 garbage collect 되지 않을 때 발생한다.

application에서 memory leak이 발생시키지 않은 경우에도 gc 옵션을 잘못 지정하여 발생할 수도 있는데, 흔히 발생했던 원인 중 하나는 JVM에서 CMS (Concurrent Mark and Sweep) gc 알고리즘을 지정한 경우이다.

CMS gc 알고리즘에서는 기본값으로는 perm area 에 대해 gc를 하지 않는다.

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6329603

이 경우 해결책은 CMS 알고리즘을 쓰지 않거나 다음 옵션을 추가하는 것이다.

-XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled

최근에 이와 다른 이유로 perm area 에서 OutOfMemoryError가 나는 경우가 있어, heap dump를 분석해본 적이 있다. 뜻밖에도 remote 객체가 ClassLoader를 reference하고 있어서 ClassLoader가 gc되지 못한 경우였다.
RMI 혹은 EJB (JRMP)를 사용하는 application이었는데 gc가 안정적으로 실행되도록 -XX:+DisableExplicitGC 옵션을 켜놓았었다.

-XX:+DisableExplicitGC 옵션은 System.gc() 메소드를 호출해도 아무 일이 일어나지 않도록 한다.
이 때문에 분산 gc가 제대로 수행되지 않아서 ClassLoader가 gc되지 못하였고, 결국 perm area가 full이 났던 것이다.

자바의 분산 gc (distributed gc, 즉 원격 객체에 대한 gc) 알고리즘은 기본적으로 60초마다 System.gc() 메커니즘에 따라 full gc를 요청하게 된다.
이때, 더 이상 사용하지 않는 원격 객체에 대한 참조 count를 떨어뜨리고, 더 이상 원격 객체에 대한 참조가 없으면 unexport를 하게 된다.

이 간격을 늘리려면 기본값인 60,000(60초)을 3,6000,000(1시간) 정도로 바꿔주면 된다.

-Dsun.rmi.dgc.client.gcInterval=36000000
-Dsun.rmi.dgc.server.gcInterval=36000000

분산 gc가 발생할 때마다 full gc가 일어나는 것 때문에 시스템 성능이 급격히 떨어지는 것을 막기 위해 다음 요청이 접수되었다.

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5025281

Sun에서는 JDK 1.6부터는 다음 JVM 옵션을 사용할 수 있도록 개선하였다. 또 dgc 간격 기본값을 1분에서 1시간으로 늘렸다.

-XX:+ExplicitGCInvokesConcurrent

이 옵션이 설정된 경우는 System.gc()가 호출되더라도 gc 알고리즘이 concurrent gc 인 경우 full gc가 일어나는 것이 아니라 concurrent gc 를 실행한다.

따라서, RMI나 EJB를 사용하는 경우의 HotSpot VM 튜닝은 다음을 권장한다.

1. -XX:+DisableExplicitGC 은 설정하지 않는 게 좋다.
2. JDK 1.5 이하일 경우에는 dgc interval을 늘려준다. 보통 1시간 정도면 괜찮다.

 -Dsun.rmi.dgc.client.gcInterval=36000000
 -Dsun.rmi.dgc.server.gcInterval=36000000

3. JDK 1.6 이상일 경우에는 다음 옵션만 켜주면 큰 문제가 없다. dgc interval은 기본값이 이미 1시간으로 변경되어 있으므로 수정할 필요가 없다.

-XX:+ExplicitGCInvokesConcurrent