[Info]Tags categorized posts and contents patterns..

[AJAX] Ajax Code E xamples.. [Book] About the book.. [CSS] CSS Code E xamples.. [DB] Sql Code E xamples.. [DEV] All development stor...

2016년 4월 6일 수요일

[Book] 해커와 화가..

출처 : Outsider's Dev Story https://blog.outsider.ne.kr/

해커와 화가 - 10점
폴 그레이엄 지음
임백준 옮김
한빛미디어

해커와 화가는 2005년도에 출간된 고전(?)이라고 할 수 있습니다. 오랫동안 보고 싶었지만 절판되어서 구할 수가 없었던 관계로 읽지 못하다가 얼마 전에 교보문고에서 이북을 판매한다는 것을 발견하고 잽싸게 구입해서 읽었습니다. 다음 목차에서 보듯이 에세이처럼 쓰인 이 책은 전체가 하나의 큰 흐름을 가지고 있다기보다는 챕터별로 다른 주제의 얘기를 하고 있고 들은 얘기로는 폴 그레이엄이 인터넷에 올린 글을 보아서 낸 책으로 알고 있습니다.

  • 01 공부벌레들은 왜 인기가 없는가
  • 02 해커와 화가
  • 03 우리가 말할 수 없는 것
  • 04 좋은 불량 태도
  • 05 또 하나의 길
  • 06 부자가 되는 법
  • 07 차이에 대한 연구
  • 08 스팸을 위한 계획
  • 09 창조자의 미적 취향
  • 10 프로그래밍 언어에 대한 설명
  • 11 100년 후의 프로그래밍 언어
  • 12 평균을 뛰어넘기
    13 공부벌레의 반격
  • 14 꿈의 언어
  • 15 디자인과 연구
폴 그레이엄은 야후 웹스토어(국내에선 그리 보급되지 못한듯 합니다. 별로 기억에 없네요.)의 근간이 된 비아웹을 만들었으며 그 뒤에는 Y Combinator를 만들었습니다. Y combinator는 현재 Hacker News를 운영하고 있습니다. 이 책을 읽으면서 놀라운 점은 폴 그레이엄의 통찰력입니다. 이미 6년이나 된 책임에도 이 책에서 폴 그레이엄이 예상하고 있는 부분은 대부분 현재 그대로 현실화되었다고 생각됩니다. 가볍게 읽을 수 있으면서 곰곰이 생각해 보면 많은 인사이트를 주는 책이라고 생각합니다. 제가 어떤 문제에 대해서 생각했을 때 관련된 정보를 많이 얻게 되는 것을 자주 경험합니다. 그 타이밍에 그런 고민을 다들 하기 시작한 것인지 아니면 그런 고민을 하다 보니 더 눈에 들어오는 것인지는 정확하지 않지만, 이 책이 제게 그러했습니다. 비록 오래된 책이기는 했지만 제가 고민하는 부분에 대한 정리된 생각을 알 수 있었습니다. 챕터별로 다른 이야기라 전체 요약은 어렵고 인상 깊은 얘기 위주로 정리하겠습니다.

초반부에는 해커에 대한 설명이 나옵니다.

해커와 화가의 공통점은 우선 그들이 둥 다 무언가를 창조한다는 사실이다. ...중략... 사실대로 말하자면 해커들은 표현의 자유에 대한 열망에 사로잡혀 있는 사람들이다.
제목처럼 해커와 화가를 비유하고 있습니다. 해커와 화가가 비슷하다고 얘기하는 것인데 그는 처음부터 끝까지 창조하기 때문입니다.

해커가 수행하는 일은 가끔 "소프트웨어 엔지니어링"이라는 말로 불리기도 하는데 이것은 컴퓨터 사이언스에 못지않게 잘못된 인식을 심어준다 ...중략... 진정한 해킹이란 사실 요구사항 자체를 창조하는 것이다. 요구사항을 만들어 내는 최선의 방법은 그것을 실제로 구현해 보는 것인 경우가 많다.
폴 그레이엄은 컴퓨터 사이언스라는 말이나 스프트 엔지니어링이란 말에 거부감을 가지고 있습니다. 이는 요구사항의 정의와 구현 즉 이는 "무엇"과 "어떻게"라는 개념을 나누는데 이 두 개념은 나누어질 필요가 없다고 말하는 것입니다. 그래서 다음과 같이 얘기합니다.

컴퓨터 사이언스처럼 해커가 하는 일이 과학이라고 불린다면 그들의 행동 역시 과학적이어야 한다는 부담감이 생기기 때문이다. 그래서 대학과 연구소에서 일하는 해커들은 아름다운 소프트웨어를 설계하는 것처럼 진심으로 원하는 일에 몰두하는 대신, 연구논문 같은 것을 작성해야 한다고 느끼게 된다. ...중략... 무언가 아름다운 것을 만드는 방법은 대개 이미 존재하는 것을 살짝 뒤틀거나 아니면 알려진 아이디어 몇 개를 새로운 방식으로 결합하는 것인 경우가 있다. 이와 같은 종류의 일은 연구 논문에서 설명되기 어렵다.
회사라고 해서 해커가 하고 싶은 일을 하도록 그냥 내버려두는 곳은 아니다. 대학과 연구소는 해커에서 모종의 과학자가 될 것을 강요하는 반면, 회사는 그들에게 엔지니어가 될 것을 요구한다. 야후에 해커로 남고 싶다고 대답한 이후 그들이 말하는 해킹은 내가 알고 있는 것처럼 소프트웨어를 디자인하는 것이 아니라 단지 구현하는 것에 불과함을 알게 되었다.
컴퓨터 사이언스라고 불리는 곳에서는 너무 "무엇"에만 집중하고 엔지니어링이라고 불리는 곳에서는 "어떻게"에만 집중하고 있다는 것입니다. 좋은 소프트웨어가 나오려면 "무엇"과 "어떻게"가 함께 이루어져야 한다고 이야기하고 있는데 여기에 무척 공감하고 있습니다. 폴 그레이엄을 비아웹을 만든 뒤 성공해서 야후에 인수된 후 야후 웹스토어로 발전하게 되는데 그 과정에서 스타트업에 대해서 일하다가 대기업에서 일하게 됩니다. 그래서 다음과 같은 이야기가 나옵니다.

대부분의 회사는 소프트웨어의 미래를 한 명의 천재적인 해커에게 맡기기보다는, 소프트웨어가 여러 명으로 구성된 팀에 의해서 설계되도록 하고 해커들은 다만 그것을 구현하도록 만든다. 만약 여러분이 언젠가 큰돈을 벌고 싶다면 이것을 잘 기억해두기 바란다. 왜냐하면 스타트업 회사가 승리할 수 있는 비결 중 하나이기 때문이다. 큰 회사들은 최악의 재난을 피하기 위해서 디자인 산출물에 대한 표준 편차를 줄이려고 노력한다. 하지만 활기차게 진동하는 기운을 억누르면 진동의 저점만이 아니라 고점도 함께 상실하게 됨을 기억해야 한다.
소프트웨어는 그것에 대해서 아무 것도 모르는 사람들이 아니라 그것이 설계된 방식을 잘 이해하고 있는 해커에 의해서 만들어져야 한다.
이는 제가 최근에 많이 생각하는 부분이기도 합니다. 회사라는 구조에서 특히 큰 회사일수록 이상하게도(?) 도저히 좋은 소프트웨어가 나올 수 없는 구조로 되어 있습니다. 이 시스템 혹은 이 프로세스에서는 도저히 좋은 소프트웨어, 창의적인 제품이 나올 수 없다는 생각이 들게 합니다. 저로서는 아무도 말은 그렇게 하지 않지만 목표 자체가 최고의 제품을 만드는 것이 아니라 고만고만한 제품을 만들어서 기존의 인프라를 활용하는 것이 목적이라고까지 생각하고 있습니다. 사람마다 의견이 다르기는 하겠지만(제가 다 옳은 것은 아니니) 이건 웹에 대해서, 제품에 대해서 과연 이해가 있는 것인가 하는 회의감에 빠져들기 일쑤입니다. 그러면 어떻게 해야 하는가에 대한 고민으로 이어질 수밖에 없는데 폴 그레이엄은 자신의 경험을 토대로 어느 정도의 답과 방향을 제시해 줍니다.

결국 훌륭한 소프트웨어를 만드는 방법의 하나는 자기 자신의 스타트업 회사를 만드는 것이다. 그렇지만 여기엔 두 가지 문제가 있다. 우선 스타트업 회사 안에서 당신은 소프트웨어를 작성하는 일 이외에도 여러가지 다른 일을 해야한다.  ...중략... 스타트업과 관련된 또 하나의 문제점은 돈을 벌어주는 소프트웨어와 작성하기에 흥미로운 스프트웨어 사이에는 별로 겹치는 부분이 없다는 사실이다. ...중략... 만약 돈을 벌고 싶다면 자기에게 흥비로운 일을 찾을 것이 아니라 너무나 짜증나는 일이라서 누구도 그것을 공짜로 해결할 엄두를 내지 않는 힘겨운 일을 찾아야 할 것이다.
이 글처럼 스타트업이 어느 정도의 대안이 될 수 있지만 완전한 대안이 되지 못합니다. 대기업의 불필요하고 효율적이지 않은 프로세스만 사라졌을 뿐 스타트업이어도 돈을 벌기 위해서는 자신이 하고 싶은 것이 아닌 고객이 원하는 것을 할 수밖에 없습니다.

이 문제에 대한 답은 적어도 소프트웨어의 경우에는 모든 창조자들에게 이미 잘 알려져 있는 해법으로 구해야 할 것이다. 그것은 임시직(day job)이다. 임시직이라는 표현은 사실 밤무대에서 공연하는 음악인들로부터 시작되었다. 좀 더 일반적으로 말하자면 임시직이란 돈을 벌기 위해서 하는 일과 열정을 위해서 하는 일이 별개의 것임을 의미한다. ...중략... 한편으로 뭔가 멋진 소프트웨어를 개발하기 위한 일을 진행해야 한다는 게 새로운 아이디어는 아니다. 오픈소스 해커들이 하는 일이 바로 그것이기 때문이다. 내가 말하고자 하는 것은 결국 오픈 소스야말로 올바른 모델이 아닌가 하는 점이다.
사실 이 방법이 제가 최근 1,2년 사이에 다다른 결론입니다. 임시직을 뛰고 있다는 얘기가 아니라 돈을 벌기 위한 일과 제가 하고 싶은 일을 완전히 분리해 버렸다는 것입니다. 처음에는 의도한 것은 아니고 회사에서 하고 싶은 일을 못하다 보니 다른 곳에서 그럴 수 있는 것을 찾게 되었고 그런 것을 어느 정도 찾게 되자 거기에 열정을 퍼붓게 되었습니다. 그러면서 회사라는 조직에서 과연 하고 싶은 일을 할 수 있느냐는 고민을 하게 되었고 어차피 두 가지가 결국 합쳐질 수 없다면 차라리 너무 바쁘지 않은 안정적인 직장으로 돈을 벌고 제가 하고 싶은 것을 따로 하는 게 낫겠다는 결론에 이르렀습니다. 알란 케이의 말을 약간 패러디한다면 "열정을 가질 수 있는 일과 회사의 업무가 일치하는 것이 가장 좋다고 생각합니다. 하지만 아직 그러한 회사를 한 번도 보지 못했기 때문에 둘을 분리했습니다." 물론 이는 회사에 업무에 대해서 일정 수준이 상은 열정을 들이지 않는 결과(문제인가요?)가 되기도 합니다.

해킹을 정말로 좋아한다면 뭔가 자기 자신의 프로젝트를 수행하지 않고는 견딜 수가 없는 것이다. ...중략... 그림은 무언가를 그림으로써 학습한다. 해킹도 마찬가지다. 대부분의 해커들이 대학에서 프로그래밍 수업을 받는 것으로 해킹을 배우지 않는다.
하지만 당신이 사실은 노란색의 권리보다 다른 일에 더 관심이 있다면, 노란색주의자라는 딱지는 방해가 될 것이다. 바보들과 논쟁을 하면 당신도 바보가 되는 것이다. 가장 중요한 점은 당신이 원하는 것을 말하는 것이 아니라, 그냥 생각하는 것이다. 그리고 만약 당신이 스스로 생각하는 모든 것을 입 밖으로 내어 말한다면, 그것은 파격적인 생각을 사색하는 데 방해가 된다. 정반대의 노선을 취하는 것이 옳다는 게 내 의견이다.
폴 그레이엄은 대형 기업의 문제점을 정확하게 지적하고 있습니다.(아마 이 문제들은 대형 기업들은 문제라고 생각하지 않을 것 같습니다.)

나는 갑자기 큰 회사를 위해서 일하고 있는 스스로를 발견하게 되었는데, 그것은 마치 허리까지 물에 잠긴 상태에서 달리려고 하는 기분과 비슷했다. ...중략... 작은 회사에 비해서 10분의 1정도만 생산적이다. 큰 회사는 이보다 더 나을 수 없다.
당신이 수행한 일이 다른 사람들이 수행한 일과 함께 하나의 평균값으로 뭉뚱그려지는 것이다. ...중략... 내가 보기에 큰 회사들이 가지고 있는 제일 심각한 문제는 바로 개개인의 업무를 어떻게 제대로 평가하는 가이다. 그들은 대개 정확하게 평가하는 것을 포기해 버린다. ...중략... 눈에 뜨일 정도로 무능하거나 게으르다면 곤란하겠지만, 그렇다고 해서 당신의 삶 전체를 회사에 바칠 필요도 없다. ...중략... 그보다 더 심각한 문제는 회사 입장에서 보았을 때 당신이 수행한 일의 진정한 가치를 정확하게 측정할 수 있는 방법이 전혀 없다는 것이다.
대기업은 무겁고 느립니다. 퀄리티만 떨어지는 것이 아니라 효율도 같이 떨어집니다. 폴 그레이엄의 말처럼 두 번째 문제가 더 큰데 평가할 수 없는 것을 평가할 수 있다고 착각하고 있습니다. 제 기준에서만 봤을 때는 좋은 평가를 위해서는 오히려 가치가 없거나 불필요한 일을 엄청나게 해야 하는 것처럼 느껴질 정도입니다.(저는 KPI라는 평가제도가 세상에서 제일 멍청한 제도 중 하나라고 생각합니다. 다른 분야는 모르겠지만, 개발에는 분명합니다.) 프로그래머가 하는 일은 어떻게 평가해야 하는가에 대해서 어떻게 평가할 수 있는가를 고민했었는데 폴 그레이엄이 어느 정도의 의견을 제시하고 있습니다.(실제 회사에서 적용할 제도적인 기준은 아니라고 할지라도...)

해커가 진짜로 하는 일을 측정하는 것, 즉 그가 아름다운 소프트웨어를 설계하는지 여부를 가리는 것은 훨씬 어려운 일이다. 좋은 설계인지 여부를 판단하기 위해서는 판단하는 사람 자신이 이미 좋은 설계에 대한 감각을 가지고 있어야 하기 때문이다. ...중략... 아름다운 소프트웨어인지 아닌지 측정할 수 있는 유일한 외적인 방법은 시간이다. 시간이 지남에 따라서 아름다운 것은 번창하고 못난 것은 사라진다.
그리고 이 책은 해커의 특성에 대해서 잘 설명하고 있습니다.

말하자면 순수한 호기심 인 것이다. 어쨌든 나는 금지된 것이라면 무엇이든지 궁금해서 견딜 수가 없다. 내가 보고 결정하게 하라. 두 번째로, 나는 잘못 이해되는 관념이 존재한다는 게 마음에 들지 않기 때문이다. ...중략... 세 번재로, 이런 사고방식은 두뇌 활동에 도움이 되기 때문이다. 훌륭한 일을 수행하기 위해서는 우선 당신의 두뇌가 가볼 수 있는 모든 곳을 열심히 가보는 것이 좋다. 특히 누군가 거기는 안 된다고 말하는 곳에 가보는 습관은 두뇌 활동에 더더욱 도움이 된다.
권력을 가진 사람들은 대개 해커들이 가지고 있는 고분고분하지 않은 태도때문에 불편함을 느낀다. 하지만 불복종이라는 것은 훌륭한 프로그래머를 만들어 내는 특성의 부산물이다.
감시는 나쁜 아이디어가 승리하는 세상을 만들어 낸다. 해커에게 옳은 아이디어가 승리하는 사회를 갖는 것이 너무나 중요하기 때문에 그런 조짐들에 대해서 남보다 민감하다.
테크놀로지가 가져온 변화에 대해서 설명한 부분은 꽤나 인상적이었습니다. 일반적으로 세상의 부를 고정된 파이에 비유해서 누군가 부를 늘리면 다른 사람의 부가 줄어든다는 말을 하고 있지만 그렇지 않다고 강조하고 있습니다.

테크놀로지는 부를 창출하는 것이 그것을 훔치는 것보다 더 빠를 수 있는 길을 열어 놓았다. ...중략... 잡스와 워즈니악은 부자가 되기 위해서 다른 사람을 가난하게 만들 필요가 없었다. ..중략.. 확실한 것은 그것이 생산적인 사람과 그렇지 않은 사람사이의 차이를 더욱 넓힐 것이라는 점이다. 그것이 테크놀로지의 핵심이다. ...중략... 테크놀로지가 값싸게 만들 수 없는 유일한 대상은 브랜드다. 우리가 요즘 브랜드에 대해서 많이 듣게 되는 이유가 바로 이것이다. 브랜드는 그러니까 부자와 가난한 자 사이에 존재하는 실질적인 차이가 증발하면서 남게 된 찌꺼기와 같은 것이다.
현대 사회에서 수입에 있어서의 차이가 늘어나는 것이 오히려 사회가 건강하다는 사실을 나타내는 것이라고 주장하고 싶다. 테크놀로지는 생산 능력에 있어서의 차이를 선형 비율보다 빠르게 증가시키고 있다. 만약 수입에 있어서의 차이가 그 증가속도를 따라가지 않는다면 거기엔 세 가지 설명이 가능할 것이다.
(a) 기술적인 혁신이 중단되었다.
(b) 가장 많은 부를 창출할 만한 사람들이 일을 하지 않는다.
(c) 부를 창출하는 사람들이 제대로 보답 받지 않는다.
이 책에서는 회사의 윗사람을 머리 솟은 보스에 비유하면서 비판을 하고 있습니다. 이는 사실 프로그래밍 언어의 선택에 대해서 이야기하면서 나온 부분으로 적재적소에 맞는 기술을 사용하지 않고 보편적인 기술만을 사용하게 되는 데 대한 이야기를 하면서 나오는 부분입니다.

극히 드문 두 개의 성질을 불가사의하게 한 몸에 결합하고 있다. (a) 그는 테크놀로지에 대해서 아무 것도 아는 것이 없다. 그리고 (b) 그는 테크놀로지에 대해서 매우 강한 의견을 가지고 있다. ...중략... 소프트웨어가 어떻게 동작하는지 알지 못하고, 어떤 프로그래밍 언어를 다른 언어와 구별하지도 못한다. 그럼에도 불구하고 그는 당신이 어떤 언어를 사용해야 하는지 잘 알고 있다. ...중략... 그에게 자바는 곧 표준이다. ...중략... 세상에 존재하는 프로그래밍 언어가 모두 동일한 것이라고 착각하고 있는 것이다.
덜 유명한 언어를 사용하는 데 따르는 문제로 세 가지 정도로 생각해 볼 수 있다. 우선 프로그램이 다른 언어로 작성된 프로그램과 함께 어울려서 동작할 때 제대로 동작하지 않을 수 있다. 사용할 수 있는 라이브러리가 제한될 수도 있다. 그리고 프로그래머 고용이 어려울 수도 있다. ...중략... 첫 번째 문제의 의미는 당신이 시스템 전체를 통제할 수 있는가 이다. ...중략.. 호환성 문제가 발생하면 다신 스스로 문제를 해결할 수 있다. 서버기반 어플리케이션에서는 가장 진보적인 테크놀로지를 사용할 수 있는데, 조나단 에릭슨이 말한 "프로그래밍 언어의 르네상스"의 의미가 여기에 있지 않은가 생각한다. ...중략...라이브러리에 대해서 말하자면, 중요성은 어플리케이션에 달려있다. ...중략.. 그정도 규모의 프로젝트라면 강력한 언어의 기능이 미리 존재하는 라이브러리의 편리함을 앞지르기 시작할 것이다. ...중략.. 우리는 이제 최고의 소프트웨어는 열 명 이하의 사람으로 이루어진 팀에 의해서 만들어질 수 있다는 사실을 분명히 알게 되었다. 열 명 정도의 수준이라면 누구라도 한 번 쯤 들어본 언어를 사용하는 프로그래머를 고용하는 데 아무런 문제가 있을 수 없다.
좋은 해커가 되기 위한 자세 혹은 스타트업으로써 취해야 할 자세를 다음과 같이 이야기 합니다.

감정이입이라는 것이 자기희생을 뜻하는 것은 아니다. 그것과는 거리가 상당히 멀다. 사물을 다른 사람의 입장에서 바라본다는 것은 곳 다른 사람의 이익을 대변한다는 뜻은 아닌 것이다. ...중략... 다른 사람의 주의를 끌기 위해서는 그들이 필요한 것이 무엇인지 이해해야 한다. ...중략... 아마도 감정이입이야 말고 그냥 좋은 해커와 위대한 해커를 구분하는 결정적인 차이점일 것이다.
쉽게 생각할 수 없는 것을 생각할 수 있도록 자신을 훈련시키는 일은 평상시의 생각을 뛰어넘도록 도와준다. 달리기 전에 몸을 충분히 푸는 것은 달리는 행위 그 자체보다 몸을 훨씬 더 유연하게 준비시킨다. 다른 사람의 머리가 곤두설 정도로 파격적인 생각을 자유자재로 할 수 있다면 흔히 혁신이라고 부르는 수준의 미미한 파격을 시도하는 것은 문제도 아닐 것이다.
우리가 일부러 어려운 문제를 찾으려고 노력했다는 사실이다. 우리는 소프트웨어에 더할 수 있는 기능이 두 가지 있을 때, 그리고 기능이 가진 가치가 어려운 정도에 비례한다고 했을 때, 언제나 어려운 쪽을 선택했다. 더 많은 가치를 위해서가 아니라, 더 어렵기 때문이다. ...중략... 우리에게 어려움이라는 것은 경쟁자에게는 불가능을 의미했기에 우리는 그렇게 힘든 날에도 즐거움을 잃지 않았다.
좋은 작품을 만드는 데 필요한 자기만의 미적 취향을 가지고 있어야 한다. ...중략... 진정한 문제는 단순해지도록 강제되었을 때 만나게 된다. 더 이상 무의미한 장식물을 동원할 수 없게 되었을 때, 실질적인 내용을 보여주어야 하기 때문이다. 좋은 디자인은 시간을 뛰어넘는다. ..중략... 유머가 결여된 채 좋은 디자인으로 불리는 것을 상상하기가 쉽지는 않다.
시간의 벽을 뛰어넘는 것을 목표로 삼는 일은 최선의 해결책을 발견하기 위한 하나의 방법이 될 수 있다. 어느 누군가가 당신의 일을 뛰어넘는 것을 상상할 수 있다면 그 일을 스스로 해야 한다. 인류의 위대한 스승들을 바로 그러한 일을 철저하게 추구했기 때문에 자기 뒤를 이은 사람이 할 수 있는 일의 여백을 별로 남겨 놓지 않은 사람들이었다.
좋은 소프트웨어를 작성하려면 두 개의 상반되는 생각을 머릿속에 동시에 가지고 있어야 한다. 초짜 해커가 갖는 자신의 능력에 대한 순진한 확신과 베테랑이 품는 회의감을 모두 가지고 있어야 하는 것이다. 그리하여 한쪽 머리로는 도대체 그것이 어려워 봤자 얼마나 어렵겠어? 라고 생각하고, 다른 쪽 머리로는 아냐, 그건 절대로 동작하지 않아. 라고 생각할 수 있어야 한다. 이러한 과정에는 아무런 모순이 없다는 점을 깨닫는 것이 포인트다. 당신은 두 개의 다른 사물에 대해서 낙관과 비관을 하고 있는 것이다. 문제를 해결할 가능성에 대해서는 낙관해야 하지만, 당신이 그 시점까지 개발한 해결책의 가치에 대해서는 끊임없이 회의를 해야 하는 것이다. 좋은 작품을 산출하는 사람들은 대개 그들이 일하는 동안에는 자기가 현편없는 작품을 만들고 있다고 생각한다. ...중략.. 근심이 좋은 작품을 만드는 것이다.
무엇이든 맨 처음에 제대로 만들어 내기는 어려운 법이다. 전문가들은 처음에 만든 작품은 내다 버리게 될 것이라고 생각한다. 그들은 항상 변화를 염두에 둔다.
마지막으로 이 책을 읽고 나면 리스프(Lisp)를 배워보고 푼 생각이 들게 되면서 내년에는 Clojure를 배워볼까라는 망상을 잠시 해 봅니다. ㅎ 참고로 폴 레이몬드가 만든 비아웹은 리스프로 만들었습니다.

리스프가 대단한 이유는 리스프가 가장 강력한 언어이기 때문이다. 다른 사람들이 그것을 이용하지 않는 이유는 프로그래밍 언어라는 것이 단순히 테크놀로지가 아니라 습관이기 때문이다.
" 리스프는 그것을 마침내 손에 넣게 되었을 때 경험하게 되는 심오한 깨달음을 위해서라도 배울 가치가 있다. 리스프를 이용할 일이 그렇게 많지 않다고 할지라도 그 경험은 그 자체만으로도 당신을 훨씬 훌륭한 프로그래머로 만들어줄 것이다." - 에릭 레이몬드의 "어떻게 해커가 되는가(How to Become a Hacker)"
그동안 구할 수가 없어서 못 읽기는 했지만, 과연 사람들이 추천할 정도의 책이구나 하는 생각이 들게 하는 책입니다. 이런 책이 절판되어서 더 이상 구할 수가 없다는 건 정말 안타까운 일이군요.


[EP]H3 Developers Conference 2011 후기 #2..

출처 : Outsider's Dev Story https://blog.outsider.ne.kr/

개발자를 위한 고급 Git 활용전략 - 김상영
Git명령의 대부분은 File보다는 Commit 객체를 다룬다는 점을 알아야 하고 Git의 명령어를 이해하기 위해서는 HEAD와 브랜치가 단순한 포인터라는 것을 기억해야 합니다.

이 발표는 말로 정리하기는 어려운 부분이 있어서 Aj가 올려주신 발표자료를 첨부했으니 이 내용을 보시는게 이해하기가 훨씬 쉬울 것입니다. 처음 설명은 HEAD와 브랜치에 대한 설명이었습니다. Git의 커밋객체들이 자신의 부모 커밋들을 참고해서 링크드리스트처럼 연결되고 HEAD는 이에 대한 포인터로의 역할만 합니다. Branch도 마찬가지로 다른 커밋객체를 가리키는 새로운 포인터일 뿐입니다. 이를 자바스크립트의 객체에 비유해서 설명했는데 명확하게 이해하기가 쉬운 비교였습니다. 다만 자바스크립트로 비유할 때 커밋객체의 parent대신에 prev로 설명했는데 혹 git을 잘 모르는 사람은 prev라는 속성이 있는 것으로 오해할까 싶기도 했습니다.(머 그걸 오해한다고 큰 문제가 생기는 것은 아닙니다. ㅎ)

뒷부분은 Git저장소의 해부에 대한 내용입니다. git저장소를 만들면 .git폴더안에 많은 파일들이 생기고 git로 작업할 때마다 이 폴더안에 새로운 파일들이 생기게 되는데 이 구조에 대한 설명이었습니다. 커밋객체는 커밋할 때 생기지 않고 git add할 때 생기는데(git add할때 생기는건 블랍객체이고 커밋객체는 커밋할때 생깁니다.)  .git/objects안에 생기고 블랍파일입니다. git blob format는 헤더를 포함해서 zlib으로 압축을 합니다. git hash-object 명령어를 사용하면 파일에 대한 해쉬명을 알아낼 수 있고 해시화된 파일은 git cat-file로 그 내용을 알 수 있습니다.

왜 해쉬를 사용했는가 하면 중복이 나올 확률이 무척 적으며 육안으로 구별하기 어려운 간단한 차이도 해시에서는 쉽게 구별할 수 있습니다. 그래서 Git에는 4개의 객체가 있는데 모두 파일로 존재합니다.

  • Blob : .git/objects안에 존재합니다.
  • Tree : 폴더처럼 트리안에 트리가 존재하고 그안에 Blob가 존재할 수 있고 .git/objects안에 있습니다.
  • Commit : 리스트입니다. 이전 커밋을 참조하는 Parent, tree, author, date등의 속성을 가지고 있고 .git/objects안에 있습니다.
  • Tag : 커밋객체에 대한 포인터로 .git/refs/tags아래 있습니다.

Git에는 Working Area, Staging, Repo 3가지 스페이스가 있습니다. 각 명령어를 실행할 때마다 이 스페이스 사이에 리스트가 만들어지는 것이고 이 리스트를 통해서 비교가 됩니다. 그리고 리셋옵션은 리셋할 스페이스를 지정하는 것입니다. --soft는 Repo까지 --mixed는 Staging까지 --hard는 Working까지 리셋한다는 의미입니다.

Aj와 개인적인 친분도 있었기 때문에 초기에 이 발표에 대한 설명을 들은적이 있었는데 그때는 사실 잘 이해가 되지 않고 너무 어려운 얘기를 하시려는게 아닐까 생각했었습니다. 그뒤에 여러번의 과정을 거쳐서 발전되어 실제 발표할 때는 너무나 깔끔한 설명이 되었습니다. Git에 대해 궁금하신 분은 이 발표자료를 꼭 참고하라고 하고 싶습니다. 개인적으로는 이날 제일 유익한 세션이었네요.

많은 Git에 대한 발표들이 GIt의 명령어에 대한 것이었다면 이번 발표는 Git의 내부구조에 대한 설명이었는데 이해를 돕기 위해서 자바스크립트의 변수에 비유해서 설명하였는데 아주 이해하기 쉽고 최근에 제가 궁금해 하던 부분이기 때문에 무척 유익했습니다. Git을 시작할 때 이런 부분을 이해하고 사용해야 한다는 것은 아니지만 단순히 clone - commit - push만 하는 것 이상의 작업을 하려면 반드시 내부구조에 대한 이해가 반드시 필요합니다.

UX에 대한 7가지 오해와 진실 - 김수영
이 세션을 저로써는 잘못 선택한 세션이었습니다. 저는 사실 UX자체에 대한 내용으로 생각하고 들어갔지만 실제로는 UX에 대한 얘기가 아니라 UX팀과 UX팀의 업무에 대한 얘기였습니다. 그래서인지 오후가 되어서인지 좀 집중하지 못하고 들었습니다.


많은 얘기가 있었지만 간단히 요약하면 위 사지의 7가지가 오해이고 아래 사진의 7가지가 그 진실입니다. 내용이 요약으로 하기는 좀 어려워서 사진으로 대체합니다. ㅡㅡ;;


이런 부분은 UX만 아니라 상당부분은 QA팀이나 기획팀에 적용해도 크게 이상하지 않았을꺼라고 생각하고 있습니다. 저도 UX에 어느정도 관심이 있는데 사실 많이 알지 못합니다. 저는 사실 국내에 UX에 대해서 제대로 아는 사람이 얼마나 있는가에 대해서 좀 회의감을 가지고 있는 사람입니다. UX라는 단어가 인기를 끈 뒤에 많은 회사에 UX라는 조직이 생겼지만 제대로 UX를 하고 있는지는 잘 모르겠습니다. 발표내내 들은 느낌은 KTH의 UX조직은 개발과 프로젝트의 전반적으로 관여하고 품질향상을 위해서 상당히 노력하는 것으로 보였는데 아마 저는 이렇게 UX와 일을 못해봐서 그렇게 느끼고 있었는지도 모르겠습니다.

제가 느끼는 UX조직의 문제는 UX라는 단어의 모호함(어쩌면 모호하다기 보다는 대부분 쉽게 이해못하는...)때문도 있지만 UX라는 것이 그렇게 표가 나지 않는 작업입니다. UX라는 것은 아주 다양한 곳에 적용되지만 아주 간단한 예로는 주민등록번호를 입력하면 생년월일이 자동으로 입력된다는 등의 일이 있습니다. 당연히 이는 무척 중요하고 사용자의 편의성을 크게 높여주지만 사실 잘 표가 나지 않습니다. 조직내에서 우리 UX팀이 좋은 UX를 만들어냈다는 것을 윗분들에게 보여주기가 다른 쪽에 비해 쉽지 않다는 것입니다.(대부분 윗분들은 UX를 깊이 이해못하고 있으니까요.) 그래서인지 어느 조직이든 그렇듯이 UX팀의 존재성을 증명하려다 보니 좀 이상한 UX까지 억지로 들어가는 느낌이 없잖아 이다고 생각하고 있습니다.

암튼 이런건 개인적인 생각이고 다른 분들은 좋았다는 사람들도 많았던것 보니 아마 기대감의 차이였던 것 같습니다. 전 UX전문가한테 UX에 대해 자세한 얘기를 좀 듣고 싶었거든요. 발표를 들으면서 다른 UX조직도 KTH처럼 다방면으로 노력하면서 하는지 궁금하다군요.(그렇다면 제가 UX에 대한 오해를 가지고 있었던 것이겠지요. ^^;;)

파이썬으로 클라우드 하고 싶어요 - 하용호
이 세션의 주제는 파이썬으로 분산처리도 해보고 병렬처리도 해보고 클라우드도 써보자였습니다. 지금은 시대가 빅데이터와 분산처리를 필요로 하고 있습니다. 가장 간단한 것은 한 컴퓨터내의 멀티코어를 잘 사용하는 것이고 그 다음은 여러 머신을 사용하고 그 다음은 클라우드를 사용하는 것입니다. 하지만 분산프로그래밍은 어려운데 배우기도 어렵고 쓰기도 어렵고 실행하기도 어렵습니다. 이렇게 어려운 이유는 작성하는 것이 어렵고 라인수도 무척 길어집니다. 그리고 네트워크나 디스크가 병목점이 될 때가 많고 의외로 반복사용하기도 어렵습니다.

여기에 대한 해답이 파이썬이고 파이썬을 사용하면 생각의 속도로 코딩을 할 수 있습니다. 국내에서는 인기가 높지 않지만 파이썬도 쉽고 쉽게 쓸 수 있는 라이브러리도 많이 존재하고 파이썬이 느리기는 하지만 어차피 네트워크나 디스크로 인한 병목점이 많이 발생하기 때문에 파이썬의 속도는 크게 문제가 되지 않습니다.

멀티코어를 잘 사용하려면 쓰레드를 여러개 사용해야 합니다. 간단한 덧셈프로그램을 하나의 쓰래드로 했더니 3.5초가 걸렸는데 쓰레드를 2개로 늘렸더니 오히려 4.2초가 걸렸습니다. 파이썬도 파이썬 버츄얼머신상에서 동작하는데 이는 GIL(Global Interpreter Lock)때문에 발생하는 문제입니다. 보통 시스템이 락이 걸때 Coarse-grained락이라는 큰 락을 거는데 성능이 좋지 않고 작업당 락은 거는 Fine-Grained락은 작은 락이라 성능은 좋지만 만들기가 쉽지 않습니다. 파이썬은 전체를 락으로 거는 단 하나의 락을 사용합니다. 그래서 쓰레드를 여러개 사용하더라도 락이 하나이기 때문에 하나의 CPU가 일을 하면 다른 CPU는 놀고 있습니다.

GIL을 사용하면 인터프리터 구현이 쉽고 GC만들기도 좋습니다. 파이썬이 GIL을 도입했을 때는 1990년대였기 때문에 싱글CPU였지만 지금은 멀티코어가 일반화되었기 때문에 이부분이 오히려 장벽이 되었습니다. 그래서 쓰레드로 할 수 없으면 프로세스로 할 수 있습니다. GIL은 프로세스에서만 유효하기 때문에 CPU별로 프로세스를 구분해 주어 작성하면 앞의 덧셈프로그램을 프로세스 2개로 1.88초만에 계산할 수 있습니다. 사실 이건 꼼수가 아니라 분산프로그래밍에서는 오히려 정답입니다. 쓰레드라는 것은 하나의 PC내에 존재하는 것이지만 분산은 여러 머신에 걸처서 해야 하는 것입니다. 파이썬에는 Parallel Python이라는 라이브러가 존재하는데 여러 프로세스에 분산해 주는 역할을 합니다. 사용하기도 쉽고 잘 동작하는데 싱글머신의 멀티코어에도 사용할 수 있고 워커머신 자동찾기 기능도 있습니다.

이제 클라우드를 사용해 보겠습니다. 맵리듀스는 2004년 OSDI의 구글 발표에서 이야기 나온 것입니다. 맵리듀스는 사실 어려운게 아닌데 누구나 많은 양의 작업을 해야한다면 생각해 낼 만한 작업입니다. 예를 들어 책에 나오는 단어의 갯수를 세어보는 작업을 해야한다면 여러명에게 일을 나눠주고(map) 나눠준 결과를 다시 모으는 것도 힘들기 때문에 일정단위로 분단장을 뽑아서 종류별로 모으도록(reduce)하는 것입니다. 맵리듀스가 인기있는 이유는 하둡때문입니다.

하둡이 등장하기 이전의 분산처리는 어떻게 분배해야 하는지 프로그램을 어떻게 원격에 전송하고 나눈 작업을 어떻게 스케쥴링해야하는지에 대해서 고민해야 했지만 하둡의 등장으로 어떻게 Map을 작성하고 Reduce를 작성하는지만 고민하면 나머지는 하둡이 다 알아서 해줍니다. 그래서 슈퍼개발자가 아니러도 분산처리를 할 수 있게 되었고 분산이 유행하게 되었습니다. 하둡은 자바로 만들어졌지만 HadoopStreaming을 이요하면 어떤 언어에서도 사용할 수 있습니다. HadoopStreaming에 관심을 가진 업체는 Yelp인데 이 회사는 사장부터 파이썬 매니아라서 mrJob이라는 라이브러리를 만들었습니다. mrJob을 사용하면 하둡없이도 로컬에서 테스트할 수 있고 runner부분만 바꾸어 주면 하둡에서 동작하게 할 수 있습니다.

분산프로그래밍을 하려면 많은 머신이 필요한데 회사에 머싱이 많지 않다면 아마존의 ElasticMapReduce가 좋은 대안이 될 수 있습니다. 아마존이 OS와 하둡을 설치해 놓아서 비용만 지불하면 이용할 수 있습니다. 가격도 저렴해서 라지인스턴스 기준으로 7.5G 메모리에 4CPU 100대를 한시간 써도 6불만 지물하면 된다. ElasticMapReduce도 mrJob에서 지원하고 있어서 runner만 emr로 바꾸면 자동으로 ElasticMapReduce에서 실행한뒤에 결과를 S3로 전송해 줍니다.

원래는 이 시간대에 다른 세션을 들으려고 했습니다. 클라우드에는 관심이 있었지만 파이썬은 할 줄 몰랐기 때문에 제가 들을 만한 세션인지 잘 몰랐기 때문이지요. 하지만 컨퍼런스 몇일전부터 트위터에서 이 세션이 엄청 재밌다는 홍보가 많이 있었고 주위사람들도 들으러 간다기에 같이 들어갔습니다. 들어가고 보니 안들어왔으면 엄청나게 후회했을 좋은 세션이었습니다.

기본적으로 내용이 탄탄하고 좋았습니다. 설명을 너무 잘하셔서 내년에는 파이썬을 배워보고 싶은 마음이 들 정도였습니다. 파이썬과 분산프로그래밍의 연결에서 흐름과 예제까지 자연스럽게 잘 구성이 되어 있어서 몸이 지친 마지막 세션이었음에도 집중해서 들을 수 있었습니다. 더군다나 중간에 개그를 계속 하셨는데 개그가 완전히 제 코드라서 너무 재밌게 들었습니다. 좋은 내용에 적절한 개그까지 발표스타일이 너무 맘에 들더군요.

Epilogue
개인적으로 너무나 흡족한 컨퍼런스였습니다. 처음하는 세미나라고 믿기 어려울 만큼 컨퍼런스가 좋아서 상당한 기간동안 열심히 준비했다는 것을 느낄 수 있었습니다.


H3에서 가장 인상깊었던 것은 바로 이 책입니다. 이 책은 (모든 세션은 아니지만) 발표자들이 세션의 내용을 글로 적은 내용을 책으로 묶은 것입니다. 단순히 발표자료를 프린트해서 한 것이 아닌 글을 자세히 새로 적었습니다. 이는 제가 생각하는 발표라는 방향과도 부합하는데 사실 발표자료는 발표를 돕는 역할이기 때문에 발표없이 발표자료만 보면 이해하기가 어려운게 사실이고 그냥도 볼 수 있는 발표자료를 만들려면 원래 의도에 제대로 맞출수 없습니다. 발표는 발표로 하고 자세한 내용을 읽어볼 수 있도록 이렇게 제공했다는 점에서 이번 컨퍼런스를 얼마나 열심히 준비했는지 알수 있습니다.

저는 컨퍼런스나 세미나는 한두가지 인사이트나 괜찮은 세션정도면 만족하는 편인데 H3에서는 대부분의 세션에 만족감을 느낄정도로 퀄리티가 좋았습니다. 이는 대부분 보안이라고 감추는 사내에서 직접 업무를 하면서 고민했던 부분과 개발한 부분을 그대로 공개했기 때문에 세션들이 무척 실용적이면서도 내용이 탄탄했습니다.

그리고 많은 사람들이 트위터에 H3의 만족감에 대한 트윗을 올라서 30일 타임라인에서 최대의 이슈였던것 같습니다. 그런 글 중에 많은 글에서 xguru님으로 인해 달라진 KTH에 대한 얘기가 많이 있었는데 제 생각은 약간 다릅니다. xguru님이 KTH에 오신 이후로 대외적으로 많이 알려진 것은 사실이지만 이번 컨퍼런스를 통해서 KTH가 겉으로 드러나는 부분만이 아닌 다양한 부분에서 오랫동안 탄탄히 준비한 것이 느껴졌습니다. 그리고 이 뒤에는 KTH 부사장인 박태웅님이 있다고 생각하고 있습니다. 지금 이 수많은 개발자들을 끌어들이며 KTH가 순신간에 영향력을 가지게 된 것은 박태웅님이 그 주역이라고 생각하고 사실 xguru님을 끌어들인것도 부사장님인걸로 알고 있습니다.

꽤전에 KTH에서 전사원들에게 엄청나게 열심히 기술을 전파하는 부사장님 얘기를 들은적이 있었지만 사실 그다지 신경쓰진 않았습니다. 실제로 어떤지는 제가 알 수 없었고 대부분의 윗분들은 기술을 잘 모르는데다가 사실 이해하려는 마음도 그다지 없이 주변에서 주위들은 기술지식만으로 섣부르게 몰아쳐서 피곤해지는 경우가 훨씬 많았기 때문입니다. 그러면서 트위터를 통해서 많은 얘기나 요즘은 직원분들과 얘기하는 것을 많이 보았는데 제가 아는 범위에서는 거의 유일할 정도로 비기술자이면서 기술에 대한 제대로된 관점을 가진 임원입니다. 기술자가 아님에도 기술자와 비슷한 관점을 가지고 있고 이제는 그 기술에 대한 판단을 제대로 해줄 능력있는 개발자들까지 갖추어진 상태입니다.(나중에 혹시 이력서를 쓸지도 모를 상황을 위해서 아부하려는 것은 아닙니다. ㅡㅡ;;)

암튼 H3컨퍼런스내내 상당히 즐거웠습니다. 최근 KTH가 유명한 개발자들을 많이 데려가면서 저는 이러한 최근행보를 아주 좋게 보고 있고 꼭 성공(?)하길 바라고 있습니다. 그래야 그런 분위기가 다른 곳으로도 퍼질 수 있을테니까요. 사실 과거에는 KTH는 IT에서 그다지 안중에도 없는 회사였지만 최근에는 NHN, Daum과 어깨를 견줄 수준까지 올라온듯 합니다. 컨퍼런스 얘기는 안하고 회사얘기만 한참 했네요. ㅎㅎ 오랜만에 좋은 컨퍼런스를 갔다왔더니 기분이 좋군요.



[EP]H3 Developers Conference 2011 후기 #1..

출처 : Outsider's Dev Story https://blog.outsider.ne.kr/

11월 30일에 KTH에서진행한 H3 Developers Conference 2011에 갔다왔습니다. 오랫동안 평일날하는 세미나에 거의 참가를 못하고 있었는데 11월에 특히 많은 세미나중에 고르고 골라서 갔다가 왔습니다.

KTH에서 주관하는 개발자 컨퍼런스는 처음이지 싶은데 일반적으로 그냥 이름을 보면 느낌이 오는 세미나와는 달리 H3가 무엇을 의미하는지 궁금했었는데 Hello Hacking Heros라는 의미였습니다. 흥미로운 세션들이 많이 있었는데 제가 들은 세션은 다음과 같습니다.

H3 시간표

키노트 : 하이브리드 앱의 미래, 앱스프레소 1.0 - 한기태
컨퍼런스의 시작은 유명하신 xguru님이 나오셔서 파란의 개발자블로그의 제목이기도 한 "개발자가 행복한 회사"라고 KTH를 소개하면서 시작하였습니다. 이어서 KTH의 대표이사이신 서정수님이 나오셔서 KTH의 최근 행보와 컨퍼런스를 개최하게 된 배경에 대해서 이야기 하셨습니다. 해외에서는 지금 개발자를 구하기가 쉽지 않은데 연봉이 십만불씩하는 개발자도 많이 있답니다. 최근 해외업체들과 일을 했는데 그쪽에서 워커홀릭이라고 알려진 개발자조차도 한국개발자들에 비하면 상대가 되지 않는다고 했답니다. 이러한 상황은 사회적 문제일 수도 있지만 지식을 공유하지 않는 문제의 탓도 있다고 생각하기에 KTH는 개발의 결과를 공유하기로 했고 개발블로그를 운영하고 외부강의를 하고 이렇게 컨퍼런스도 개최하게 되었다고 했습니다.(강대상에서 얘기하는게 아닌데 종이를 손에 들지 않고 얘기하셨으면 더 좋지 않았을까 생각합니다. ㅎ)


이어서 한기태님이 나오셔서 키노트를 진행되었습니다. 내용은 제목과는 좀 다르게 하이브리드앱의 미래라기 보다는 대부분 지금 하이브리드앱까지 오기까지 역사에 대한 설명이 대부분이었습니다. 모바일이 커지면서 엄청난 시장이 되었고 현재 아이폰과 안드로이드가 2강구도로 되어 있지만 장기적으로 가트너는 1강 3중체제를 예측하였습니다. 이들은 발전이 빠르고 기술이 달라서 회사나 개인이 둘다하기가 어렵기 때문에 크로스플랫폼 기술이 필요하게 되었습니다. 유일한 대안은 HTML5와 CSS3였습니다.

그동안 웹은 W3C가 HTML4이후에 감을 못잡는 사이에 브라우저 벤더들이 주축이 된 WHATWG의 주도로 HTML5가 진행되었고 현재는 크롬 OS나 WebOS, 모질라의 B2G까지 나오고 있는 상황입니다. 웹에서는 디바이스에 접근을 할 수 없기 때문에 DeviceAPI가 등장했지만 하이브리드 플랫폼마다 다른 API를 사용해서 파편화가 발생했지만 WAC만이 Waikiki표준을 만들었고 KTH의 앱스프래소도 이를 따르고 있습니다. 각 플랫폼은 사용자의 이탈을 막기 위해 락인을 하지만 WAC의 표준은 플랫폼 독립적이고 오픈표준입니다. 미들웨어인 WAC WRT를 이용하기 때문에 어디서나 가능하지만 지금은 OS가 오픈된 안드로이드에서만 가능합니다. 차후 윈도우즈폰과 바다도 지원하겠다고 이야기 했습니다.

폰갭이나 앱스프레소는 하이브리드 모바일 프레임워크입니다. 폰갭은 비표준 디바이스 API를 사용하고 통합개발환경이 없기 때문에 각 OS에 대한 지식이 어느정도 있어야 하지만 앱스프레소는 표준 Device API를 사용하고 있고 하나의 통합개발환경을 가지고 있습니다. Waikiki API 2.0을 정식으로 지원하고 있고 Wac 앱 팩키징을 지원하고 있으며 W3C위젯 1.0을 완벽하게 지원하고 있습니다. 앱스프레소는 무료로 제공하고 있는데 이를 유료화 할 계획은 없으며 저렴한 가격으로 클라우드 빌드와 푸시 알림을 제공할 예정이라고 합니다.

개인적으로 WAC에 크게 관심을 가지고 있지 않고 WAC이 iOS와 안드로이드를 누르고 장기적인 전망이 있다고도 생각치 않기 때문에 사실 Waikiki의 표준이란 것이 크게 의미가 있는가 생각하고 있습니다. 물론 저는 앱스프레소를 쓰고 있지는 않지만 현시점에서 가장 괜찮은 하이브리드 솔루션이라고 생각하고 있습니다. 이런 부분은 자사의 제품이니 마케팅 면에서 괜찮다고 하더라도 개인적으로는 그냥 세션중의 하나가 키노트로 나온건가 싶을 정도로 딱히 키노트같은 내용도 아니었고 너무 뻔한 얘기들이라 무척 지루했습니다. 2/3정도는 웹과 모바일의 뻔한 역사에 대한 얘기였던것 같습니다.(H3에서 가장 지루하지 않았나 싶네요.)

Google을 통해 살펴보는 분산 파일 시스템의 현재와 미래 - 김홍모
처음엔 분산파일 시스템에 대해서 설명했습니다. 파일을 관리하기 위해서 메타정보에 위치를 기록해서 빨리 찾을 수 있게 하지만 파일이 너무 많다면 여러대의 컴퓨터를 사용해야 하고 이를 분산파일 시스템이라고 합니다. 이미 많은 웹서비스들이 분산파일시스템을 사용하고 있는데 가장 많이 알려진 것인 GFS(Google File System)입니다. 구글의 데이터가 너무 많아서 직접 파일시스템을 만들었고 GFS는 단일 마스터 구조로 되어 있습니다.

Gmail 만들기
이어서 Gmail을 만드는 과정을 설명하였습니다. Gmail은 구글이 내놓은 최초의 사용자 정보중심의 인터랙션 웹서비스입니다.(저는 이런 측면으로는 한번도 생각해 본 적이 없어서 흥미로운 관점이었습니다.) 그래서 효율보다는 반응속도가 무척 중요합니다. Gmail을 사용하기 위해서 Google Servlet Engine과 GFS상에서 동작하는 DBMS인 BigTable을 사용합니다.

첫번째 방법은 GFS에 메일을 직접 저장하는 것입니다. 근데 메일이라 작은 파일들이 너무 많아서 두번째 방법인 Bigtable에 저장하였습니다. 빅테이블은 수많은 자료를 하나의 꾸러미로 만들어서 GFS가 처리해야 할 파일의 수를 감소시킵니다. 하지만 GFS는 단일 마스터노드 구조이기 때문에 장애가 났을 때는 위해서 이중화를 해야 합니다. 하지만 비용이 문제입니다. GFS의 복제정책은 같은 데이터를 3개씩 저장을 하므로 이중화를 하면 2배로 늘어납니다. 2011년 2월 27일에 구글의 데이터에 장애가 발생했습니다. 3월 1일에 열심히 복구중이고 데이터는 테이프에 있기 때문에 안전하다고 공지가 올라왔습니다. 실제 구글은 GFS에 추가로 테이프 백업까지 하고 있습니다. 백업을 하기 위해서는 어떤 작업이 종료되어야 백업할 수 있는데 Gmail같은 서비스는 멈추지 않고 운영되기 때문에 일반적인 전략으로는 백업할 수 없습니다. 그래서 구글은 스냅샷기능을 이용했는데 스냅샷기능을 이용하면 그 순간순간을 백업해야 하기 때문에 데이터의 량은 더욱 늘어납니다.

GFS를 뛰어넘자
GFS의 단점은 파일 수가 많고 마스터 장애에 취약하기 때문에 이중화가 반드시 필요해서 비용이 높아지게 됩니다. 이를 해결하기 위해서는 메타정보의 꾸러미를 도입하고 일정 메타정보를 묶어주고 이 메타정보는 원형으로 구성합니다. 그리고 이 메타정보 꾸러미를 서버와 짝을 맺어주면 서버의 장애가 발생했을 경우 시계방향에 있는 서버가 장애난 서버의 메타데이터꾸러미까지 처리합니다. 이를 분산해쉬테이블이라고 합니다.


그리고 복제를 하는 이유는 데이터를 잃어버리지 않기 위함인데 백업은 비용이 너무 많이 들기 때문에 데이터가 안전하면서도 비용을 줄일 수 있는 방법이 필요합니다. Erasure Code를 사용하면 자료의 일부를 잃어버려도 나머지 자료로 원본을 복구해 낼 수 있습니다. Erasure Code는 새로 만들어 진것이 아니라 인공위성과 데이터를 주고받거나 CD에서 데이터의 일부가 손실되어도 시디롬이 데이터를 복구할 수 있도록 만들어졌습니다. Erasure Code를 자세히 보면 자료를 여러개의 분할하고 분할된 자료를 Erasure Code를 사용해서 새로운 분할조각은 만듭니다. 그리고 이를 모두 저장하는데 이중에서 임의의 m개가 손실되어도 원본을 복구해 낼 수 있습니다. 때문에 Erasure Code를 사용하면 복제보다 비용을 절반으로 줄일 수 있습니다.

이렇게 GFS를 뛰어넘는 키워드는 분산메타관리 체계와 Erasure Code입니다. 구글도 여기에 비슷한 답을 내놓았는데 Colossus입니다. 아직 정식발표는 하지 않았지만 여러 컨퍼런스등에서 그 존재는 확인되고 있습니다. KTH가 내놓은 답은 PrismFS입니다. 현재 개발중인데 PrismFS는 분산메타관리 체계를 가지고 있고 Erasure Code로 자료를 보호하고 REST API를 제공하면 모든 자료에 check-sum을 적용하고 있습니다.

분산이 점점 인기를 끌고 있지만 저는 이런 부분을 많이 알고 있지 못해서 들었습니다. 내용이 어렵지는 않았지만 이쪽에 대해서 많이 알지 못하다보니 꽤 흥미로운 세션이었습니다. 저한테는 수준이 딱 좋더군요. 단순히 분산파일시스템에 대한 설명만이 아닌 실제 구현체를 만들기 위해서 많은 고민을 한 결과에 대한 내용이라는 것을 알 수 있었고 PrismFS가 궁금해졌습니다.

하이브리드 클라우드 활용방안 및 도입전략
- 박형준

클라우드 컴퓨팅 기술 동향
2009년부터 클라우드 컴퓨팅이 주목되는 주제로 선정되었습니다. 아쉽게도 2012년에는 순위에서 좀 밀려났습니다. 클라우드 컴퓨팅은 컴퓨팅이 발전되는 가운데 웹서비스와 그리드 컴퓨팅, 네트워크 컴퓨팅, 유틸리티 컴퓨팅이 합쳐진 것입니다. Joe Weinman은 클라우드를 다음과 같이 정의했습니다.

  • Common architecture : 공통된 리스스풀
  • Location independent : 위치에 상관없이 서비스를 제공한다.
  • Online : 온라인상으로 무중단(가급적)으로 운영
  • Utility : 사용한 만큼 지불한다. 고정된 자상이 없다.
  • on Demand : 급격히 사용량이 증가했을 때 요청에 따라 늘릴 수 있다.

클라우드는 배포에 따라 Private와 Public로 분류할 수 있습니다. Private는 내부 자산으로 운영하는 것이고 Public은 공개된 클라우드를 사용하기 때문에 사내 IT조직은 운영권한이 없습니다.
초기 클라우드는 기존기술에 비해 많이 부족했지만 현재는 좋아져서 많이 퍼블릭 클라우드로 옮겨가고 있습니다. 하지만 Private과 Public에는 장단점이 있기 때문에 둘을 혼합한 하이브리드를 선호하게 되었습니다.

하이브리드 클라우드 활용방안
Private 클라우드를 운영하면서 사용자가 갑자기 많아져서 이에 대처를 못하면 버스팅(Busting)이 발생하는데 이 버스팅을 퍼블릭 클라우드를 이용해서 할 수 있습니다. 사용량에 대한 계획은 기존 시스템의 사용량에 근거해서 산정하지만 대부분 잘 맞지 않습니다. 그래서 빠르게 확장(Scale Fast)하고 빠르게 수거(Fail Fast)할 수 있어야 합니다. 이는 가용서버를 사용량에 따라 빠르게 늘리고 줄일수 있어야 한다는 의미입니다. 아니면 퍼블릭 클라우드를 이용하면서 DR(Disaster Recovery)가 발생해서 퍼블릭을 이용할 수 없을 경우 Private으로 이에 대응할 수 있습니다. 물론 쉽지는 않습니다.

하이브리드 클라우드 도입 전략
사용자들은 플랫폼을 바꿀 때 전환비용에 대해서 생각합니다. 그래서 플랫폼 사업자들은 사용자들이 쉽게 벗어나지 못하도록 호환성을 막아서 락인합니다. 그래서 하이브리드를 사용할 때는 이러한 락인에 대해서 고민해야 합니다. 락인으로는 다음과 같은 기능들이 있습니다.

  • Unique Feature : 플랫폼에 종속적인 특수한 기능을 사용하면 이전하기 어렵습니다.
  • Contraction : 데이터 이전방법이나 사용기간등에 대한 계약등을 확인해 보아야 합니다.
    Massive Data Transfer : 데이터 이전을 어떻게 할지에 대한 고민이 필요합니다.

그래서 락인은 IaaS < PaaS < SaaS  순으로 커집니다. 이러한 락인은 개발자들에 의해서 해결되기도 하는데 M/Gateway DB는 아마존의 SimpleDB와 호환되는 오픈소스 데이터베이스로 M/DB를 통해 SimpleDB의 전환비용이 낮아졌습니다. 그리고 Public은 아마존을 사용하고 Private는 Eucalyptus를 사용해서 호환성을 유지할 수 있습니다. 두번째 전략은 관리도구에 대한 고민입니다. Public과 Private을 사용하고 Public에서도 여러가지 서비스를 사용한다고 하면 이를 어떻게 관리할 것인가에 대한 고민이 필요하고 모니터링을 위한 대시보드나 권한관리를 어떻게 할지에 대한 고민이 필요합니다.

기술세션이라기 보다는 전략이나 접근방법에 대한 이야기였지만 클라우드는 직접 써보지 않았기 때문에 재미있었습니다. 말을 정말 자연스럽게 잘하시더군요. 그냥 사내 서버 아니면 클라우드 같은 식으로만 생각했었기 때문에 이러한 하이브리드에 대한 접근은 별로 생각해 보지 않았고 그로 인한 많은 이슈들에 대해서 알게 되었습니다. 마지막으로 인간의 몸에서 심장만 암에 걸리지 않는다고 하시면서 그 이유가 심장은 계속 펌프질을 하기 때문인데 IT는 계속해서 이러한 펌프질을 해야하고 우리가 모인 이유도 그 때문이라고 하셨는데 꽤 인상적이었습니다.

클라우드 컴퓨팅 AWS 글로벌 서비스 구축을 위한 선택 - 이호철
클라우드를 선택할 때는 (1) 높은 가용성(Availability) (2) 탄력적인 용량 제공(Elastic) (3) 비용 효율화(Cost-Effective)를 고려합니다. 보통 클라우드를 싸다고 생각하는 경향이 있는데 결코 싸지 않다 여기서 비용 효율화라는 것은 확작성등을 고려했을 때의 비용효율화입니다. KTH는 AWS(Amazon Web Service)를 선택했는데 이는 앞으로 pudding.to와 Friending이라는 글로벌 서비스를 오픈할 예정인데 이를 위해서는 글로벌 CDN이 필요한데 아마존을 이용하면 쉽게 할 수 있습니다. 그리고 이 서비스들은 사진을 업로드해야하는데 물리적으로 거리가 멀면 업로드 지연은 필연적이기 때문에 AWS를 지역별로 분산하면 업로드 지연을 해결할 수 있습니다.

AWS는 전세계에 6개 지역에 위치하고 있으며 각 지역당 2개의 가용존이 있습니다. 기초 서비스로 EC2와 S3, EBS, ELB, Route 53이 있고 그위에 RDBMS, Elastic Cache, SimpleDB등으로 데이터처리를 할 수 있으며 맵리듀스도 지원하고 있습니다.

  • EC2 : Elastic Compute Cloud의 약자로 웹콘솔로 간단하게 가상의 컴퓨팅 환경을 생성하고 관리할 수 있습니다. 다양한 OS와 타입을 지원하고 있으며 기본적으로 3개의 네트워크 자원을 할당합니다.
  • EBS : 블럭스토리지로 볼륨당 1GB에서 1TB까지 지원합니다. EC2에서 마운트해서 사용하기 때문에 EC2에 의존적입니다.
  • S3 : Simple Storage Service의 약자로 데이터 스토리지입니다. 오브젝트당 1byte에서 5TB까지 사용할 수 있으며 HTTP를 사용하기 때문에 단독으로도 쓸 수 있다.
  • ELB : Elastic Load Balancing의 약자로 로드밸런서입니다. 수천대의 인스턴스를 로드밸런싱할 수 있고 Sticky Session기능으로 특정 세션을 강제로 하나의 서버에 지정할 수 있습니다. 대신에 고정 IP를 지원하지 않습니다.
  • Route 53 : 가장 가까운 DNS서버를 찾아서 응답속도를 높여줍니다. WRR(Weighted Round Robin)을 지원합니다.

확장성(Scalability)
스케일업은 보통 하드웨어의 성능을 높이는 것이고 스케일아웃은 수평적으로 서버의 댓수를 늘리는 것을 말합니다. EC2의 스케일업은 웹콘솔에서 별도로 지원하지 않기 때문에 스냅샷을 생성해서 더 좋은 EC2를 생성하고 기존 것은 죽이는 수동으로만 할 수 있습니다. RDS의 스케일업은 웹콘솔에서 옵션으로 처리할 수 있습니다. 대신 유지보수 일정주기에 따라 실행되며 변경시간동안에는 다운타임이 존재하게 됩니다. (즉시 실행해야 할 경우에는 옵션을 지정할 수 있습니다.)

EC2는 스케일아웃에 대해서 오토 스케일링을 지원합니다. 이것이 AWS를 선택하게 된 가장 큰 이유입니다. ELB가 EC2 인스턴스를 사용하고 Cloud Watch가 EC2의 인스턴스를 모니터링합니다. 이렇게 사용하는 것이 일반적이지만 KTH는 EC2에 2개의 EBS를 붙혀서 하나는 OS영역으로 사용하고 다른 하나는 애플리케이션의 영역으로 사용합니다.(이렇게 2개의 EBS를 사용했을 때의 장점은 설명하지 않으셨는데 궁금하더군요.) 오토스케일링을 위해서 인스턴스의 타입이나 이미지를 선택하는 Launch config를 생성하고 오토스케일링 그룹에서 최대로 생성할 인스턴스 갯수와 최소로 생성할 인스턴스의 갯수를 지정할 수 있습니다. 그리고 Trigger를 통해서 스케일아웃을 하는 조건을 설정할 수 있습니다. CPU나 특정시간을 지정할 수 있으며 증가/감소할 인스턴스의 갯수도 지정할 수 있습니다.

RDS의 스케일아웃은 오토스케일링은 지원되지 않고 마스터-슬레이브 구조의 리플리케이션만 지원합니다. 그리고 이때 슬레이브는 여러 지역으로 분산시킬 수 있습니다.

고가용성(High Availability)
ELB는 수천대의 EC2를 로드밸런싱합니다. 여기서 EC2를 오토스케일링 하는 구조로 만들어야 하고 같은 지역에 있으므로 가용성을 높이기 위해서 Multi-AZ구조로 만들어합니다. 이렇게 만들면 데이터베이스가 병목지점이 될 수 있으므로 디비를 마스터 슬레이브 구조로 바꿔서 구성했습니다.


성능(Performance)
성능최적화를 위해서 CloudFront를 선택했습니다. 사용자가 S3에 파일을 업로드 하면 CloudFront 네트워크를 통해서 사용자가 접속하고 CloudFront에 파일이 없으면 S3에서 가져와서 캐싱을 하기 때문에 이후의 사용자는 캐싱된 파일로 제공합니다. CloudFront는 다운로드뿐만 아니라 스트리밍도 제공하고 있습니다. CloudFront는 저렴하기 때문에 한달에 1G정도를 사용해도 50만원정도밖에 하지 않습니다.
그리고 디비로 다 커버를 못하는 부분을 위해서 MemCached기반인 Elastic Cache를 사용했습니다. 캐시를 통해서 디비부하를 줄일 수 있는데 현재는 미동부지역만 지원하고 있습니다. 그 외의 지역에서는 EC2상에 MemCached나 Redis를 설치해서 사용할 수 있습니다.

그 밖의 팁
이번에 AWS를 구성하면서 얻게 된 몇가지 팁을 알려주었습니다. 파일을 업로드할 때 물리적인 거리로 인해서 생기는 Upload Latency는 어떤 것으로도 해결할 수 없습니다. 그래서 KTH에서는 각 지역마다 업로드 서버그룹을 구성하여 사용자는 가장 가까운 서버에 업로드를 하고 서버에서 메인서버가 있는 미동부로 전송하도록 만들었습니다. 그리고 현재는 개발단계라 크게 집중하고 있지는 않지만 서버에 대한 접근제어는 오픈시에는 매우 중요한 부분입니다. 웹서버는 80/443포트만 개방하고 아마존의 Security그룹으로 들어갈 수 있는 통로는 오직 Gateway서버를 통해서만 접근할 수 있도록 구성하였습니다. 그래서 관리자나 개발자는 게이트웨이 서버를 통해 Security그룹의 안쪽으로 접근할 수 있습니다.

아마존 클라우드에 대한 책을 보기도 했지만 실제로 써보지 않기도 했고 워낙 많은 서비스가 있기 때문에 잘 몰랐는데 이번 세션을 통해서 대부분의 서비스의 용도를 구체적으로 설명해 주어 좋았습니다. 무엇보다 단순히 서비스에 대한 설명만이 아닌 실제로 KTH가 아마존으로 서비스를 구성하기 위해서 오랫동안 고민해 온 것의 결과로써의 서비스 소개였기 때문에 어느 부분에 어떤 서비스가 필요하고 왜 필요한지 알 수 있었습니다.


[EP]봄싹 스웨거 세미나 후기..

출처 : Outsider's Dev Story https://blog.outsider.ne.kr/

지난 26일 토요일에 올해 매달 마지막주에 진행하던 봄싹 스웨거의 마지막을 장식하는 세미나가 있었습니다. 스웨거는 기존에 하던 그룹스터디와는 약간 다른 형태로 한달에 한번씩 다양한 주제로 누구나 나와서 발표하는 형태로 진행되었었습니다.(Whiteship님의 스웨거에 대한 글) 자유스러운 모임이 의도였었고 여러가지 수확도 있기는 했지만 당초기대만큼 진행되진 않았던 것 같습니다. 의도는 아무나 자신이 공부한 걸 들고나와서 나누는 형태가 의도였지만 아무래도 자발적인 발표자가 스웨거를 원활하게 진행할 만큼 많지 않았고 그러다 보니 봄싹의 주축멤버가 계속 발표를 하는 형태가 되었습니다.

봄싹의 모두가 같은 생각을 했는지는 모르겠지만 저는 지식을 서로 나누는 형태가 의도였지만 결과적으로는 단방향으로 전달하는 형태가 된듯합니다.(뭐 크게 불만까지는 없습니다. 서로 나누는게 그렇게 쉽다면 누가 고민하겠습니까.) 어쨌든 올해 중순부터는 장소도 제대로 확보하지 못하면서 어려움이 있다가 이번 세미나를 통해서 2011년 스웨거를 마무리하게 되었습니다.

SpringOne 2011 키노트 요약 - 백기선
10월 25~28일에 시카고에서 진행된 SpringOne 2GX 2011에 갔다온 내용을 간단히 요약해서 정리해 준 시간이었습니다. SpringOne은 SpringSource에서 진행하는 컨퍼런스로 Spirng 프레임워크에 대한 가장 대형 컴퍼런스입니다. 스프링원의 발표자료는 [SpringOne 2011] Spring 발표 자료에 올려져 있습니다. 스프링원에 대한 얘기라 다양한 얘기가 오갔기 때문에 기억나는 것만 적습니다.

스프링원의 첫째날 이야기 부터 시작했습니다. 키노드는 로드존슨이 다친 관계로 아드리안 콜리어가 진행했다고 합니다. 아드리안 콜리어는 스프링이 인기 있는 이유를 Simple + Powerful로 이야기 했습니다. 여기서 Simple은 간단하다는 이야기가 아니고 사용하기 쉽다는 것입니다. 그리고 스프링을 사용하면 테스트하기 쉬운(Testable) 코드를 작성할 수 있고 스프링은 오픈소스입니다.

스프링 3.1에 추가된 기능은 C:Namespace와 환경에 따라 다른 프로파일을 적용할 수 있는 Environment Profiles, 그리고 Web.xml 없이 Java로 설정을 할 수 있습니다. Cache Abstaction이 추가되었고 Java 7을 지원하고 JPA지원이 개선되었습니다. 그리고 스프링 프로젝트가 Github로 저장소를 이동하였습니다.(잘못된 내용이었습니다. 스프링 저장소의 미러를 Github에 만들었을 뿐 저장소자체가 이동한 것은 아닙니다.) 더 자세한 내용은 아드리안 콜리어의 발표자료를 참고하면 됩니다.

둘째날에 들은 세션은 Jeremy Grelle의 You want to do *WHAT* in the browser!? A heretic’s guide to building the “impossible” on the modern web이었는데 웹의 역사와 앞으로의 웹에 대해서 이야기 했다고 합니다. 앞으로 주목해야 할 기술로 HTML5와 자바스크립트를 꼽았으면 자바스크립트에서도 AMD를 특히 강조했다고 합니다.


AMD는 Asynchronous Module Definition의 약자인데 비동기로 관련모듈을 불러오는 것을 이야기하고 최근에 크게 각광받고 있습니다. 그리고 Rossen Stoyanchev의 What’s New in Spring MVC 3.1세션을 들었는데 @MVC가 2.5버전에서 소개되고 3.0에서 REST를 지원했는데 3.1에서는 consume과 produce가 추가되어서 사용하기가 좀더 편해졌습니다.(제가 스프링을 자세히 모르는데 기존에 쓰던기능을 따로 분리해서 쓰기 편하게 한 기능이었습니다.) 다음은 Keith Donald의 Modern JavaScript세션을 들었는데 자바스크립트의 핵심개념과 인기있는 자바스크립트 라이브러리에 대해서 이야기 했답니다.


그리고 노드와 스프링을 연동한 예제를 보여주었습니다. 앞단은 스프링으로 만들었고 노드의 매력적인 모듈중 하나인 Socket.IO의 리얼타임기능을 사용하기 위해서 둘을 조합한 예제였습니다. 사용자가 요청을 보내면 스프링이 RabbitMQ에 넣고 노드가 RabbitMQ에서 꺼내서 Socket.IO를 통해서 사용자한테 푸쉬하는 구조였는데 사실 현업에서 노드를 쓴다면 노드만 쓰기보다는 이런식으로 레거시 플랫폼에 섞어서 쓸 가능성이 높기 때문에 인상적인 예제였습니다.

이 다음부터는 점심준비하느라고 뒷부분은 못들었네요 ㅡㅡ;; 이 세션에 대한 예제는 백기선님의 블로그에 올라와 있습니다.

스프링 어디까지 써봤니? - 박용권
@MVC로 간단한 쇼핑몰을 만들면서 중복코드를 제거하고 어떻게 개선해나가는지 보여주는 세션이었습니다. 저한테는 수준도 딱 좋고 직접 시연하면서 보여주어서 가장 좋았던 세션입니다. 먼저 컨트롤러에서 각 요청마다 클라이언트를 생성하는 코드가 반복되는 부분을 WebArgumentResolver를 이용해서 중복을 제거했습니다.(3.1에서는 WebArgumentResolver가 다른 이름으로 바뀐것 같다고 했는데 이름이 기억나지 않는군요.) 그리고 습관적으로 @Autowired를 쓰고 있었는데 이는 DI에 대한 표준이 없을때 스프링이 만든 어노테이션으로 현재는 JSR 330에서 정의된 @Inject 어노테이션을 쓰는 것도 인상적이었습니다.

다음은 쇼핑몰이 책, 음반, 영화를 파는 쇼핑몰인 관계로 각 요청별로 전체로직은 거의 동일하지만 책/음반/영화에 대한 서비스만 달라지는 부분을 해결하기 위해서 타입을 @PathVariable로 변환해서 여러개의 메서드를 하나로 합쳤습니다. 상품 타입에 대한 변수를 String으로 받던 것을 GenericConverter인터페이스의 구현클래스를 만들어서 상품에 대한 서비스를 리턴해주도록 만들어서 Enum을 이용해서 비교하도록 리팩토링 했습니다.

이렇게 하면 내부에서 타입을 구별하기 위해서 if-else 구분이 생기는데 요구사항은 항상 변경될 수 있기 때문에 새로운 상품이 추가될 경우 if문마다 추가상품에 대한 코드를 매번 추가해 주어야 합니다. 이를 해결하기 위해서 Service Locator를 만들어서 if-else문을 제거하고 상품의 타입을 넘기면 serviceLocater가 상품에 맞는 서비스를 리턴해 주도록 리팩토링해서 아주 깔끔한 코드가 되었습니다.

그리고 일반적으로 하듯이 컨트롤러에서 @RequestMapping에서 뷰를 결정하기 위해서 보통 뷰에 대한 문자열을 리텅해 주는데 박용권님은 컨트롤러가 뷰를 선택해야 하는가에 대한 의문을 가졌습니다. 표현을 그대로 빌리자면 Spring MVC의 라이프 사이클에서 컨트롤러와 뷰리졸버가 나누어져 있기 때문에 박용권님의 고집으로는 이를 용납할 수 없었다고 합니다. 그래서 컨트롤러는 뷰리졸버에서 상품종류만 전달하고 ContentsNagotiationViewResolver를 이용해서 클라이언트에 따라서(최초 요구사항에 폰/테블릿/기타에 따라 다른 화면을 보여준다는 내용이 있었습니다.) 다른 뷰화면을 선택하도록 했습니다.전달하는데 약간의 모호함이 있었습니다. 정확히는 뷰는 컨트롤러가 선택하는게 맞고 뷰의 형태를 선택하는 것은 뷰리졸버라는 의도였습니다. 그래서 ContentsNagotiationViewResolver를 이용해서 뷰이름을 선택하고 ClientViewResolver로 요청클라이언트에 따라 다른 형태를 보여줍니다.



MVC를 사용할 때 흔히 만날 수 있는 이슈들을 어떻게 리팩토링 하는지 보여주었기 때문에 상당히 유용한 세션이었습니다. 발표자료와 예제소스는 박용권님의 블로그에 올라와 있습니다.

Spring Data - 백기선
제가 스프링도 잘 모르긴 하지만 JPA에 대해서는 더욱 잘 모르기 때문에 듣고도 다 이해하기는 어려웠던 세션입니다. 먼저 앞의 스프링원 키노트세션에서 살짝 언급했던던 XML설정 없이 자바설정만으로 프로젝트를 구성하는 예제를 보여주었습니다. 먼저 일반적인 web.xml, applicationContext.xml등으로 간단한 프로젝트를 구성하고 이를 자바설정으로 모두 대체해서 XML을 제거한 다음에도 프로젝트가 정상적으로 동작하는 것을 보여주었습니다. 그리고 자바 컨피그를 사용할 때는 컴포넌트 스캔에서 Configration과 Controller를 제외시켜주어야 한다더군요. 저는 코드로 하는 것을 더 좋아하긴 하지만 XML설정이 좋은가 자바설정이 좋은가는 호불호가 있을텐데 둘다 지원이 되니까 편한 것을 사용하면 될듯 싶더군요.

Spring Data에 대해서는 주요기능중 하나인 QueryDSL에 대해서 먼저 설명했습니다. QueryDSL을 사용하면 SQL을 다음처럼 작성할 수 있습니다.


Java
1
2
3
query.from(customer)
.where(customer.firstName.eq("Bob"))
.list(customer.lastName);

함수형태로 사용하는 것이기 때문에 자동완성을 사용할 수 있고 컴파일단계에서 오류를 발견할 수 있기 때문에 SQL을 작성할 때 흔히 하는 오타로 인한 오류를 줄일 수 있습니다. 그리고 이러한 함수들은 제공되는 것 외에 spec을 이용해서 원하는 함수를 만들어서 재사용할 수 있습니다. 그리고 쿼리를 직접 사용해야 할 때는 Custom Repo를 쓰면 됩니다. 전 SQL을 잘 못하기 때문에 이런 부분은 무척 좋아보이더군요.(못해서 안좋아하는 건지 안좋아해서 못하는건지 잘 모르겠네요 ㅎ)

더 자세한 내용은 백기선님이 올리신 발표자료와 예제소스를 참고하시면 될듯 합니다.

Epilogue
마지막으로 박용권님의 Spring Social발표가 있었는데 이 프로젝트는 개인적으로도 관심이 있어서 듣고 싶었지만 오후에 집에 일이 좀 있어서 마지막 발표는 듣지 못하고 세미나장을 나왔습니다. 저도 봄싹에 속해있는 멤버인 관계로 세미나를 준비할 때 발표에 대한 고민을 했었지만 요즘 개인적으로 바쁜 일이 있어서 발표는 하지 않았습니다.(11월에 정신없었던거 생각하면 발표했으면 민폐끼칠뻔했네요.) 백기선님과 박용권님이 수고해준 덕분에 알찬 내용으로 세미나가 진행된것 같습니다. 사람들도 꽤 많이 오셨고 다들 반응이 좋은걸 보니 기분이 좋군요.


[JAVA]Guava로 리스트에서 객체의 필드로 새로운 리스트 만들기..

출처 : Outsider's Dev Story https://blog.outsider.ne.kr/

List<Person>같은 컬렉션을 가지고 있을 때 Person클래스의 특정필드만을 가지고 새로운 리스트를 만들고 싶었습니다. for문으로 돌면서 새로운 리스트를 만들어도 되지만 Guava를 쓰면 쉽게 만들 수 있었습니다.

Java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Person.java
package kr.sideeffect;

public class Person {
  private String name;
  private int age;
    
  public Person(String name, int age) {
    this.name = name;
    this.age = age;
  }
    
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public int getAge() {
    return age;
  }
  public void setAge(int age) {
    this.age = age;
  }
}

지난번 Ordering에 대한 포스팅에서도 사용했던 Person클래스입니다.(새로 만들기가 귀찮아서...) Guava에는 List<F>를 List<F>로 바꿔주는 Lists.transform함수를 제공하고 있는데 정의는 다음과 같습니다.


Java

1
2
3
4
5
public static <F,T>
  List<T> transform(
    List<F> fromList,
    Function<? super F,? extends T> function
  )

transform함수는 변환할 대상이 되는 리스트를 받고 이 리스트를 어떻게 변환할지를 정하는 Function을 두번째 파라미터로 받아서 새로운 리스트를 만들어줍니다.

Java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// PersonTest.java
package kr.sideeffect;

import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import com.google.common.base.Function;
import com.google.common.collect.Lists;

public class PersonTest {
    
  @Test
  public void 필테스트() throws Exception {
    // given
    Person p1 = new Person("Outsider", 32);
    Person p2 = new Person("nephlim", 40);
    Person p3 = new Person("Anarcher", 35);
    Person p4 = new Person("fupfin", 43);
    Person p5 = new Person("Arawn", 33);
        
    List<Person> list = new ArrayList<Person>();
    list.add(p1);
    list.add(p2);
    list.add(p3);
    list.add(p4);
    list.add(p5);
        
    // when
    Function<Person, String> nameFilter = new Function<Person, String>() {
        public String apply(Person person) {
          return person.getName();
        }
    };
        
    List<String> result = Lists.transform(list, nameFilter);

    // then
    assertEquals(result.size(), 5);
    assertEquals(result.get(0), p1.getName());
  }
}

여기서는 Person을 담고 있는 리스트인 list에서 Person의 name만으로 만들어진 새로운 리스트를 만들려고 하는 것이기 때문에 nameFilter라는 Function객체를 만들었습니다.  이 객체는 Person타입에서 String타입으로 변환되기 때문에 Function<Person, String>으로 정의했습니다. 변환하는 함수는 클래스 내부의 apply함수로 정의하는데 apply함수는 Person을 받아서 String을 리턴해 주도록 만들었고 내부에서 name의 값을 리턴해 줍니다. 이를 Lists.transform(list, nameFilter)와 같이 사용하면 name만 담긴 새로운 리스트를 만들어줍니다.

디버그모드에서 result의 타입을 확인한 화면

list는 ArrayList였지만 transform이 리턴해주는 리스트는 ArrayList는 아닙니다. 디버그로 찍어보면 위처럼 나오는데 정확한 타입은 잘 모르겠네요. 이를 ArrayList로 변환하려면 다음과 같이 작성할 수 있습니다.


Java
1
2
// ArrayList로 변환
List<String> result = Lists.newArrayList(Lists.transform(list, nameFilter));

Lists에 static함수로 newArrayList가 제공되기 때문에 간단하게 ArrayList로 변환할 수 있습니다.

Java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Function<Person, String> nameFilter = new Function<Person, String>() {
  public String apply(Person person) {
    return person == null ? null : person.getName();
  }
};

List<String> result = Lists.newArrayList(Iterables.filter(
    Iterables.transform(list, nameFilter), 
    Predicates.<String>notNull()
  ));

만약 null에 대한 체크가 필요하다면 위처럼 할 수 있습니다. 이건 Guava의 Iterables.transform과 Iterables.filter를 조합한 것입니다. 8번라인을 보면 Lists.transform대신에 Iterables.transform를 사용해서 변환을 하고 변환된 리스트를 다시 Iterables.filter에 Predicates를 사용해서 null인 객체를 모두 제거해 주었습니다. 물론 nameFilter에서는 person이 null일 경우 null을 리턴해주도록 했습니다.

즉흥적으로 찾아보면서 쓰고 있는지라 제대로 쓰고 있는지는 잘 모르겠네요 Lists.transform외에도 Iterables.transform, Iterators.transform, Collections2.transform등이 존재하는데 제대로 안서봐서 차이점들은 잘 모르겠습니다.