2015.05.07 15:16

수학은 순수 수학(pure)나 응용수학(applied)나 모두 data를 이해하고, logic을 짜는데 더할 나위 없는 도움이 된다고 생각하고 있지만, 실제 '하드웨어'와 '컴파일러'를 이해하기 위해 컴퓨터공학에 대한 공부가 필요하죠. '수학적인 논리(logic)와 공식(formula)를 '코드'로 파싱하는 방법론에 대해서는 계속해서 공부해야 하는 성질이 아닐까 생각되어요.

프로그래밍을 크게 두 가지 성질로 나누면,

  1. 논리(logic)를 생각하는 방법 (알고리즘 혹은 수학적 사고)

  2. 하드웨어/운영체제를 포함한 플랫폼에 대한 이해

이렇게 보고 있는데, 수학은 1)번에 대해서는 무엇보다도 큰 힘이 됩니다. 2)번은 수학을 베이스로 깔고, 따로 공부하셔도 되는 부분이구요.

일단 수학(혹은 논리적 사고)을 베이스로 깔고, 프로그래밍을 열심히 공부하시면, 논리(logic)를 나누는 방법, 데이터를 분류한 뒤, 각각에 대해 합리적으로 착안하는 방법 등에 대해 눈을 뜨기 쉬울 겁니다. 또한, 하드웨어의 원리, 운영체제의 동작방식, 네트워크 이론 등 컴퓨터 공학과 커리큘럼에 포함된 다양한 과목(혹은 분야)에 대한 지식을 함께 공부하셔야 프로그래밍을 잘 할 수 있습니다.


Posted by 善 곽중선
2015.04.09 16:16

다음 주 화요일(2015/04/14) 모교 동아리 신입생들 대상으로 '폰 노이만 아키텍쳐'에 대해 강의할 예정입니다. 강의 내용은 인류가 수와 계산이라는 개념을 어떻게 발전시켜 왔고, 컴퓨터가 어떻게 발명되었는지, 그리고 현대 모든 컴퓨터 구조의 원리를 제시한 폰 노이만 박사의 연구를 설명할 것입니다.


강의를 시작하기에 앞서 질문을 하나 던지고자 합니다.


"컴퓨터는 왜 전기를 필요로 하는가?"


모든 컴퓨터는 전기가 없으면 동작하지 않습니다. 스마트폰 배터리가 떨어질까 전전긍긍하면서 여기저기 콘센트를 찾아 헤매이고, 보조 배터리를 백팩에 무장하고 다니는 것이 현대의 일상적인 풍경이 되어 버렸습니다. 그런데 우리는 -정확히 프로그래머 혹은 지망생들- 컴퓨터가 왜 전기를 필요로 하는지 이해하고 있는 것일까요?


자동차를 동작시키는데 연료가 필요하고, 세탁기를 돌리는데 전기가 필요합니다. 동력기관이 어떤 식으로 움직이는지, 열역학과 동역학에 대한 아주 기초적인 상식을 가지고 있기 때문에 대부분의 사람들은 쉽게 간단하게 설명할 수 있을 것입니다. 하지만, 컴퓨터는 왜 전기를 필요로 할까요? 전기는 어떻게 컴퓨러를 움직이는 것일까요?


어쩌면 하드웨어에 대한 이해와 관심은 소프트웨어 개발자에게 불필요한 지식일수도 있습니다. 그러나 저는 두가지 관점에서 하드웨어에 대한 기초 원리를 이해해야 한다고 생각합니다.


첫번째는 논리적인 사고를 위한 첫걸음입니다. 명령어와 문법, 함수 등을 단지 외우기만 해서는 복잡한 프로그램을 개발할 수 없습니다. 기계- 그것이 전자부품이라고 할지라도 -의 동작 방식을 익히는 것은 소프트웨어에 비해 직관적이기에 더욱 용이합니다. 하드웨어의 동작 방식과 논리 구조를 익힌 후에 소프트웨어를 접할 경우, 소프트웨어의 동작 패턴 또한 기반이 되는 하드웨어에서 데이터가 흘러가고 변화하는 과정으로 머리 속에 그려보면 이해와 응용이 빨라집니다.


두번째는 소프트웨어의 성능 문제와 설계 기법을 익히는데 큰 도움이 됩니다. 거대한 소프트웨어를 설계하기 위해서는 어떤 알고리즘과 자료구조를 사용하는가의 문제 뿐만 아니라, 자신의 소프트웨어를 어떤 하드웨어에서 동작 시키느냐 (PC, 모바일 기기, 클라이언트/서버, 클러스터링, 그리드 등등)에 따라 큰 편차의 성능을 나타내기 마련입니다. 성능 문제는 소프트웨어의 활용가치 뿐 아니라, 존재 가치를 좌우 하기도 합니다. (잘못된 설계는 너무 느리거나, 아예 동작하지 않는 결과물을 만들기도 합니다.)


마지막으로 작고하신 SF 작가이신, 아서 C. 클라크의 명언을 인용합니다.


"충분히 발달한 과학 기술은 마법과 구별할 수 없다."


기술을 제대로 이해하지 못하는 엔지니어는 최신 과학을 접한 고대인과 다를 바 없게 되는 것입니다.


Posted by 善 곽중선
2015.03.03 22:30

전에도 유사한 이야기를 한 적이 있는 것 같은데, 이번에는 조금 다른 이야기를 해보렵니다. 답변하지 않게 되는 질문의 대다수는 제가 잘 모르는 분야입니다. 어설프게 답변하거나 아는 체 하는 수준 정도로 얘기할 수 있는 것에는 답하지 않습니다. 해당 분야에 호기심이 있을 경우에는 의견이라 밝히고, 할 말이 아예 없으면 "알림 켜기"로 보이지 않는 와드를 박아두기도 합니다.


다음으로 질문자가 자신이 무엇을 질문하는지 조차 모르는 상태로 판단되면 질의응답이 혼란의 카오스에 빠질 수 있어서 자제합니다. 간혹 오지랖이 넘쳐서 질문 의도를 되묻기는 합니다만 그건 실수하고 있는 겁니다. 실수라는 걸 깨달으면 재빨리 발을 뺍니다.


마지막으로 질문자가 열정적이고 자신이 무얼 묻는지 아는데 답변 안하는 경우가 있습니다. 이런 경우 갈등에 빠지죠. 가이드 할 것인가 말 것인가? 대부분 답변을 안합니다. 어떤 상황인지 비유를 통해 이야기해 보겠습니다.

남자들 중에는 프라모델이나, 피규어를 좋아하는 사람들이 있습니다. 라즈베리파이 같은 보드를 이용한 하드웨어 매니아를 예로 들 수도 있죠. 고가의 장난감(?)인데다 섬세한 부품들로 이루어져 있습니다. 이런 걸 우악스럽게 집어던지거나, 부품들을 마구 뽑고 비트는 유치원 다니는 사촌동생이 찾아왔다면 과연 차분하게 조립하거나 다루는 법을 설명할 수 있을까요? 그냥 숨기는 편이 나을 겁니다.


남자들의 사례가 이해 안가신다면, 여자분들이 아끼는 메이크업 화장품을 어린 조카가 마구 꺼내서 얼굴에 치덕치덕 바르는 상황을 예시할 수도 있겠죠.


기술도 열정만으로 혹은 성실함 만으로 익힐 수 있는 게 아닙니다. 나이가 많건 적건 간에 선행 지식, 기초 이론을 공부할 건 해야만 합니다. 그저 열정만으로 자신의 수준을 뛰어넘는 공부에 매달리는 것은 자칫 시간낭비가 될 수 있습니다. 안스럽거나 혹은 도움을 주고 싶은 순수한 마음만으로 조언을 해준다 해도 배우는 입장에서 어렵습니다. 어린 사촌동생에게 아무리 잔소리를 한들 섬세한 피규어의 까다로움을 받아들이기 어렵고, 자칫 갈등만 생길 뿐입니다.


부디 이런 분들은 스스로 깨우치시고 다시 기초 원리를 공부하시길 코드의 신께 기도할 뿐이죠.


Posted by 善 곽중선
2015.03.03 22:28

잘 배우려면 먼저 질문을 잘하는 기술을 익혀야 한다. 꼬장꼬장 하다는 소리를 들어도 질문을 잘 못하는 사람에게 되묻는 편이다. 질문이 이상하지 않냐고? 그냥 가르쳐 주면 안되냐고 짜증 내는 친구들보다 질문을 고쳐서 다시 묻는 친구들이 성장한다.

모호하게 아는 것은 지식이 되지 못한다. 그건 그냥 데이터(data)일 뿐이다. data 와 information은 다른 것이다. data는 숫자와 문자의 무의미한 집합이며 활용할 수 없는 것이고, information은 체계적이고 가치 있으며, 활용할 수 있는 것을 말한다.

좋은 질문은 답변을 잘 분류할 수 있게 하고, 잘 분류된 답변은 찾기 용이하며, 정보와 정보 간의 연결과 조합을 통한 창의적인 응용을 가능하게 한다.

좋은 질문은 자신이 이미 아는 것과 새롭게 아는 것을 연결 시켜 지식의 피라미드를 쌓을 수 있게 하고, 무너지지 않는 단단한 구조를 만들어내지만, 나쁜 질문은 그저 모래성을 쌓는 것과 같다.


Posted by 善 곽중선
2015.02.20 13:29

한동안 접고 살던 Spring framework오픈 소스를 다시 꺼내 분석한다면 나는 어떻게 할까? 일단 생각해보고 정리를 하자니... 장강의 뒷물의 앞물을 밀어낸다고 - 이게 아닌가? 아무튼 생각이 유실될 우려가 있어 그냥 냅다 적어보기로 한다.


남의 소스를 분석한다는 것은 남의 생각 속을 여행하는 것에 비유할 수 있다. "여행"을 하려면 무엇이 필요한가? 아니, 길을 잃지 않기 위해서는 무엇이 필요한지 생각해보자. "GPS"과 "지도"가 필요할 것이다. 그리고, 내가 가야할 길은 아직 가보지 않은 길이기 때문에 욕심 부리지 않는 '자세'를 준비하자. (무심결에 나침판이라고 적고 보니... 21세기인데.. 라는 생각이 들어 고쳤다.)


항해(navigation)를 시작하기 전에 준비물이 잘 갖추어 있는지 확인해 보자.


1. GPS (Global Positioning System)


프로그래머에게 필요한 GPS는 당연히 실제 물리적인 장치가 아니다. 소스를 분석할 때, 내가 어떤 소스를 분석하고 있으며, 다음으로 어느 소스를 분석해야 하는지를 판단하는데 필요한 도구이다.


내가 생각하는 소스 분석에 필요한 GPS 도구들은 다음과 같다. 프로그래밍 언어론에 대한 기초 지식 혹은 프로그래밍 언어 문법에 대한 정확한 지식이다. 언어를 모르는 사람이 소스를 분석하겠는가 라고 반문하겠지만, 남의 소스를 분석하다 보면 평소에 모르던 키워드나 연산자 혹은 문법을 마주치는 법이 생기게 마련이다. 막다른 골목에 다다르는 것과 같은 현상이 벌어진다. 즉, 머리속이 하얗게 지워진다. 이전까지 분석한 게 다 머리 속에서 지워지고 만다. goto 명령어는 자바에도 있다. 안쓸거라고 생각지 마라. 다중 루프에서 고속으로 탈출하기 위해 사용되는 경우도 간혹 있다. final 이 클래스에 붙어 있을 때 그 의미를 파악하지 못하거나, public 수식어가 없는 클래스의 의미를 모르면 오픈 소스 설계자의 진의를 절대 파악할 수 없다. 문법 공부할 때 뒷장은 건너뛴 사람은 분석하다가 오도가도 못하는 신세에 빠지는 경우가 많다. 언어의 문법을 일부만 알고 오픈 소스를 분석하는 것은 단어 몇개만 배우고, 사전도 없이 뉴욕 한복판에서 엠파이어 스테이트 빌딩을 찾는 것과 같다.


다음으로 상속과 합성에 대한 개념이다. 상속과 합성은 이정표에 해당한다. 객체지향이건 절차지향이건 간에 소프트웨어는 항상 '부품'들이 조립되는 방식으로 구축된다. 그런데, 상속과 합성의 개념을 제대로 모르면 위아래로 이동해야 하는지, 좌우로 움직이야 하는지 모르게 된다. 그리고 코드를 따라가다가 어떻게 되돌아 가야 하는지 모르게 된다. 미로에 빠지고 말 것이다. 그냥 상속만 익히면 된다고 생각지 말라. 인터페이스와 구현체 간의 관계 등을 모르면 지나쳐도 되는 코드와 코드들의 집합인 모듈 단위를 전혀 알아 볼 수 없게 된다. 코드는 단순히 작은 메소드들의 무수한 나열이 아니다. 작은 단위들이 모여 큰 단위를 이루고 작고 큰 구조를 표현하기 위해 인터페이스 상속과 패키지 개념들이 있는 것이다. 모르고 보면 아무리 보고 또 봐도 까만 건 코드, 하얀 건 배경일 뿐이다.


리팩토링은 몰라도 된다. TDD도 필요 없다. 다만, 디자인 패턴은 알아야 한다. 패턴을 이해하는 것은 운전 면허 시험을 배울 때, 교차로와 순환로 등 다양한 도로 형태를 배우는 것과 동일하다. 사람은 익숙한 지형이나 형태를 보면 깊이 생각할 필요도 없이 반사적으로 움직일 수 있다. 소스 분석도 이와 같다. 패턴을 모르면 그만큼 분석하는데 드는 시간이 기하급수적으로 늘어난다.


이클립스 혹은 IntelliJ 같은 IDE 사용 방법에도 능숙해야 한다. 탐색기를 이용해서 소스를 하나씩 열어보거나, notepad++ 로 수많은 소스를 열어 본다면? 노가다로 시간 낭비하지 말자. 상위 클래스, 하위 클래스, 참조 위치 등등 단축키만 알면 아무리 멀고 먼 위치도 워프(warp) 할 수 있는 순간이동 능력을 갖출 수 있게 된다. 다만, 앞서 말한 상속과 합성 개념이 머리에 박혀있지 않으면 금새 지나온 길을 잃어 버리게 된다.


API와 라이브러리에 대한 경험... 코드를 따라가다 보면 자칫 너무 깊이 파서 땅속으로 파고 들 수 있다. 궁금하다고 클릭하다 보면 어느새 JDK 소스를 보고 있다는 사실 조차 모르게 된다. 그럴리 없다고 생각지 말라. JDK를 설치하면 소스도 따라온다. IDE에 decompiler를 설치해두면 클릭 한 번에 지하세계로 떨어진다. 라이브러리도 마찬가지인데, 자칫 내가 프레임워크를 분석하고 있는 건지 라이브러리 코드를 분석하고 있는 건지 혼란에 빠지게 된다. 더 심하면, 프레임워크가 의존하고 있는 라이브러리와 프레임워크를 구분하지 못하는 일체의 경지에 빠지게 된다.


2. 지도 (map)

무턱대고 서울 간다고 지도도 없이 나서면, 어느 산골 구석이나 경찰서 유치장에서 발견될 수도 있다. 오픈소스를 막무가내로 이해하려는 개발자라면, 소프트웨어에 대한 환멸을 느끼고 IT 업계를 영영 떠날 수도 있다.


가급적 분석하고자 하는 오픈소스에 대한 설계에 대해 많은 정보를 제공하는 책을 구해야 한다. 오픈소스를 창작자가 서술한 책이면, 창시자의 철학을 옅볼 수 있기 때문에 가장 좋고, 없다면 가장 두꺼운 책을 사야 한다. 두꺼울수록 다루는 부분이 많기 때문에 분석하면서 낯선 코드를 만나는 경험이 줄어든다. 책을 통해 큰 흐름과 전체 얼개를 파악하면 많은 시간을 절약할 수 있다. 책을 사기 싫다면 해당 오픈 소스의 홈페이지의 introduction, user's guide, 그리고 각종 reference 문서를 최대한 많이 읽어두면 좋다. 책도 안사고, 홈페이지에도 안 가 봤다면 분석을 포기해라. 당신이 수재 이상의 머리를 가지고 있지 않다면... 샹 폴리옹인가? 그럼, 구글 가라.


영어가 싫다면 해당 오픈 소스에 대해 언급된 국내 블로거들의 글을 최대한 검색해서 많이 읽어라. 그 어떤 책이나 블로그 글도 오픈 소스 전체를 설명할 수는 없지만, 부분에 대한 이해만 해도 길을 찾는데 큰 도움이 될 것이다. 그리고, 사전에 해당 오픈 소스에서 많이 쓰이는 클래스/ 메소드 명칭에 익숙해지면 좀 더 소스가 자연스럽게 읽힌다. 인간의 두뇌는 익숙한 것일수록 해석 속도가 매우 빨라지기 때문이다.


마지막으로 종이와 연필을 준비해라. 소스를 분석하면서 눈에 띄는 소스 파일 명칭과 메소드 명칭들을 적고, 클래스 다이어그램과 시퀀스 다이어그램을 그려본다. 직접 지도를 만들라는 것이다. 종이에 적으라는 이유는 우선 컴퓨터 화면에는 소스만 띄워놓아야 집중이 잘되고 덜 산만하다는 것이고, 사람 머리는 손으로 무언갈 쓰거나 할 때 논리회로가 잘 돌아간다. 참고로 Robert C Martin 선생님이 말씀하시길 UML을 그리는데 있어서 가장 좋은 도구는 종이와 연필이라고 했다.


내가 선호하는 오픈 소스 분석 방법은 디버거(debugger) 혹은 로그 분석을 해보는 것이다.어플리케이션을 디버그 모드로 실행하면서 stack trace을 추적해보거나, 분석하고자 하는 위치에 break point를 걸어둔 후에 정지 시키고 나서 해당 위치가 실행되기 이전과 이후를 분석한다. 때로는 일부러 예외를 발생시킨후에 로그를 분석하기도 한다. 대다수의 오픈 소스는 debug, trace 로그 출력을 제어할 수 있기 때문에 상당히 긴 로그를 분석할 각오가 되어 있다면, 로그 출력 수준을 높이고 (TRACE 레벨) 프로그램을 실행시켜 보는 것도 한 방법이다. 당연히 log4j 혹은 logback 환경 설정을 선행하는 것은 필수 작업이다.

Posted by 善 곽중선
2015.02.20 13:27

한참을 내달리고 있는 프로젝트에 뒤늦게 합류해서, 선행팀이 늘어놓은 짐들을 정리하는 중입니다. 덕분에 주말에도 나와서 코드를 분석하게 되었죠. 프로젝트 파트 리더라는 역할에다가 Application Architect라는 역할을 더하고 있기 때문에 주중에는 거의 회의 참석에 시간을 뺏기게 되고 주말에야 조금 코드를 들여다 볼 수 있습니다.


오늘 분석하게 된 코드는 Code Generator 입니다. 데이터베이스의 스키마 정보를 읽어내서, VO(Value Object), DAO(Data Access Object), CRUD (Create, Read, Update, Delete) 쿼리, 웹 페이지에서 입력받은 데이터에 대한 검증 코드(validator)까지 자동으로 생성하는 모듈입니다. 작년에 다른 프로젝트에서 이러한 기능을 이클립스 플러그인 형태로 만들어서 프로젝트 팀원들이 낭비하는 시간을 줄여준 적이 있기 때문에 가벼운 마음으로 분석을 시작했습니다.


그러나, 정작 엉뚱한 곳에서 분석 흐름이 막혀 버리더군요. 제 경험으로 이해하기 어려운 코드들이 보이는 것입니다. 예를 들자면 ...Wrapper, ...Resolver 라는 클래스인데 정작 속성(property)와 입출력(getter/setter) 메소드 외에는 별다를 로직이 없더군요. 이거 어디서 많이 본 명명 패턴(naming pattern) 인데 잘못 적용했구나, 왜 이런 식의 의도하지 않은 실수가 나왔을까? 하는 생각이 꼬리에 꼬리를 물었습니다. 그리고 참 많은 생각을 하게 되었습니다.


일단, ~er 이라는 접미사(postfix)를 왜 붙이는지 따져 봅니다. 무언가 단일 행위에 대한 책임을 전담하는 클래스에 대해 ~er이라는 접미사를 붙이고는 합니다. 즉, 일반적으로 ~er로 끝나는 클래스는 Value Object 같은 데이터 보관 및 전달 역할에 쓰이지 않을 것라고 암묵적인 합의를 가지고 있습니다. 이런 원칙 혹은 관습은 어느 학회나 표준화 단체에서 정한 것이 아니라 관습으로 내려온 것이죠.


그럼 이런 관습을 우리가 따라하게된 근거는 무엇일까요? 앞서 언급한 접미사들은 Spring framework에 익숙하신 분들이 많이 보셨을 겁니다. 바로 Spring framework를 창시한 로드 존슨(Rod Johnson)과 그의 동료들( 유겐 할러 Juergen Hoeller 등)에 의해 굳어진 패턴입니다. 또, 예전에 스프링 프레임워크 3.0를 처음 접했을 때, 무턱대고 '토비의 스프링 3.0'을 저술하신 이일님 님에게 메신저로 이렇게 질문해 본적이 있습니다. 대체 스프링 프레임워크는 어떤 역사를 가지고 있느냐고, 기원(origin)이 무언가 라고 말입니다. 토비님 왈, 그냥 어느 날 로드 존슨이 만들어서 세상에 내놓았습니다.


우리가 익숙하게 써 온 기술들의 대다수, 업계 표준(de-facto standard)라고 알고 있는 것들, 원래 그런 것이다.. 라고 하는 것들이 수맣은 개발자들에 의해 합의되고 고쳐지고 또 개선되어 온 것이 아니라, 소수의 선각자(pioneer)들에 의해 어느 날 뚝딱 만들어진 것입니다.


스프링을 수많은 개발자들이 모여서 만들지는 않았습니다. 스프링 기반의 상용 프레임워크 - 전자정부 프레임워크 같은거죠... -를 설계 및 개발했을 때, 스프링 소스를 이리저리 분석해봤습니다. 거의 대다수의 소스에 작성자(author) 및 수정자 이름으로 로드 존슨과 유겐 할러의 이름이 적혀 있더군요. 스프링 프레임워크가 견고하고, 그 설계의 일관성이 유지된 이유는 수 많은 개발자들이 협력해 만들지 않았기 때문입니다. 이것은 역설처럼 들리지만, 또한 진실입니다. 많은 SI 프로젝트에서 개발자를 더 투입하면 일정이 줄어든다고 생각하지만, 이러한 생각이 틀렸다는 것은 이미 오래 전부터 피플웨어 (톰 디마르코, 티모시 리스터 지음) 같은 책에서 설파되어 왔습니다.
아키텍쳐를 제대로 이해하고, 핵심 모듈에 대한 품질을 유지하면서 프레임워크 혹은 핵심 엔진를 만들기 위해 소수의 개발자, 바로 아키텍트(architect)들이 필요한 것입니다. 헨리 포드가 컨베이어 벨트 기반의 분업 시스템를 만들고 난 이후, 급격하게 공장 생산성이 늘어 났습니다. 에디슨이 전구를 상용화 - 발명한 것인지는 논란이 있죠 - 한 후, 인류의 밤이 없어지게 되었습니다.


이렇듯 점진적이지 않은 급격한 진화의 사례는 소프트웨어 업계에서도 많습니다. 아틀란타 행 비행기 안에서 만난 구루(guru) 2분, 켄트 벡(Kent Beck)은 자바를 배우고 싶었고, 에릭 감마(Erich Gamma)는 켄트벡의 스몰토크 테스트 프레임워크를 배우고 싶어 하다 두사람은 3시간 정도 일한 끝에 junit을 만듭니다. 지금은 보편적으로 쓰이는 UML(Unified Modeling Language)은 이바 야곱슨(Ivar Jacobson), 제임스 럼바(James Rumbaugh), 그래디 부치(Grady Booch) 3인방의 아이디어와 저술을 근간으로 하고 있습니다. 디자인 패턴(Design pattern)은 어떻습니까? 건축계의 아키텍트 크리스토퍼 알렉산더의 아이디어를 소프트웨어 공학에 적용한 것이고, 소프트웨어 디자인 패턴 핵심은 GoF (Gang Of Four) 에릭 감마(Erich Gamma), 리차드 헬름(Richard Helm), 랄프 존슨(Ralph Johnson), 존 블리시디스(John Vlissides) 4분에 의해 정리되었습니다.


작년에 모 금융 프로젝트를 2 계층에서 3계층으로 재구축하는 차세대 프로젝트를 수행하면서 경량의 TCP 서버 모듈을 구현하고자 Netty 를 분석 및 활용한 바 있습니다. 이희승(Trustin Lee)님이 만드신 경량 TCP/IP 프레임워크인데, 정말 객체를 우아하게 다루는 기법을 체험하고 싶으시다면 Netty 소스 분석을 권합니다. (감동 받다가 울 뻔 했습니다...) Netty 역시 여러 사람이 아닌, 거의 모든 설계를 이희승 님이 하신 것으로 알고 있습니다.


이 글은 열심히 일하는 소프트웨어 개발자들이 만든 코드를 힐난하기 위해 쓴 것이 아닙니다. 아키텍쳐와 코딩 패턴, 그리고 표준과 품질 등 일반적으로 소프트웨어 개발자들이 평소에 신경 쓰지 못하는 부분들이 얼마나 중요하고 그것을 지키기 어려운지 이야기 하고자 하는 것입니다. 또한, 왜 아키텍트(architect)가 필요한지 그들(혹은 우리들이) 어떤 일을 하는지 이야기 하고 싶었습니다. 다수의 개발자가 협력해서 만드는 시스템은 코딩 패턴의 일관성, 간결함, 우아함, 정교함 등의 좋은 소프트웨어가 가져야 할 덕목을 유지하기 어렵습니다. 코딩 표준을 지키도록 강제한다면, 혹은 정적/동적 코드 분석 툴(Code Analysis Tool, PMD 등)을 이용해 코드의 품질을 강제한다면 반대로 독창적이고 효율적인 코드를 만들어 내기 어렵습니다.


개발자들은 아키텍트가 어려운 용어만 늘어놓고, 비싼 몸값을 받는다고 생각합니다. 아키텍트는 개발자들이 아무 것도 모르면서 덮어놓고 비난만 한다고 생각합니다. 사실 서로 협력해야 마땅합니다. 다수의 개발자들이 사용하지 않는 기술과 프레임워크는 도태되어 사라질 뿐입니다. 반대로, 일반 업무 개발자가 아키텍트의 역할과 무거운 책임, 그리고 그들이 감내해야 하는 엄청난 수고에 대해 이해하지 못한다면 앞서 사례를 들어드린 절름발이 코드들이 난무하게 되는 것입니다. 아키텍쳐에 스며있는 숨어 있는 철학과 의도를 파악하기 어렵기 때문에, 또 그 철학과 패턴을 초지일관 고수하는 것이 너무나 힘들기 때문에 모든 프레임워크와 거대한 규모에 이르는 시스템은 소수의 아키텍트들이 책임져야 하는 것입니다. 단지, 그들이 욕심꾸러기이기 때문은 아닙니다.


앞서 소수의 아키텍트에 의해 성공한 사례들을 말씀드렸지만, 다수가 협력해 프레임워크를 만드는 것이 어려운 사례를 들어보자면 스프링 배치(Spring Batch) 프레임워크를 들 수 있습니다. 스프링 프레임워크의 한 갈래이지만 스프링의 사상을 이해하지 못한 결과, 어정쩡한 구조에 폭포수 모델(Water Fall) 기반으로 뚝딱 개발했다는 인상을 여전히 지우지 못하고 있습니다. (스프링이 최대 강점은 유연함인데, 스프링 배치는 향기 없는 꽃 같은 느낌을 주더군요.)


저는 아키텍트의 역할을 이야기할 때, 영화 매트릭스를 떠올립니다. 영화 속에서 Neo는 최종 보스(?)인 아키텍트를 만납니다. 아키텍트는 자신이 새로운 세상(New World), 새로운 패러다임(paradigm)를 만들고, 인간들에게 행복을 선사했다는 듯이 자만합니다. 하지만, Neo는 아키텍트가 만든 세상을 거부합니다. 아키텍트와 개발자들의 관계가 이와 같지 않나 싶습니다. 아키텍트는 새로운 패러다임을 설계하고, 개발자들은 붉은 알약 혹은 파란 알약을 선택하죠.


Posted by 善 곽중선
2015.02.20 13:23

발전이 없는 없는 사람은 늘 새로운 것들을 기웃거리고, 자신이 가진 것과 아는 것을 수련하려고 하지 않는다. 발전하는 사람은 일단 아는 것에 집착한다.


Test Driven Development, Refactoring, 객체지향 원칙들, 디자인 패턴... 모르는 것들 그리고 고수들이 대단하다고, 알아야 한다고 말하는 것들에 현혹되지 말라. 어차피 그것들을 아는 사람, 알아야 한다고 말한 사람들도 초보 시절부터 깨닫고 처음부터 그렇게 코딩한 적이 없다.


발전이 없는 사람은 자신이 아는 것을 써먹기 보다는 멋지고, 화려고, 뽐내기 쉬운 것들을 찾아 헤맨다. 그런 것들이 쉬이 배울 수 있을리는 없다.


당장 클래스와 메소드 이름이 제대로 씌여 있는지, 불필요한 코드 블록이 넘쳐나지는 않는지... 제대로 주석을 쓰고 있는지 부터 살펴라. 정말 최선을 다한 코드를 만들고 있는가 말이다. 배운 것들을 매일 연습하고 있는가?


하루에 열 줄이라도 최선의 코드를 짜라... 그리고, 오래도록 연습하라. 그러다 보면 저절로 TDD, Refactoring, OOP, Pattern 을 이해할 수 있게 된다.


Posted by 善 곽중선
2015.02.20 13:11

정확한 단어 사용에 대해서 편집증 환자처럼 집착하는 경향이 있다. 덕분에 사람이 지나치게 까칠한 것이 아니냐고 타박을 듣기도 한다. 이런 태도에는 나름의 배경이 있다. 완벽주의 성향의 성격과 나름의 작은 철학 때문이다.


내 철학은 복잡하지 않고 심오한 고민 보다 어쩌다 꺼낸 얘기가 그대로 굳어진 것이다. 예전에 사회학을 전공하던 인문학도였던 전 여자친구와 밥을 먹다, 어떤 사상에 대한 이야기를 나눈 적이 있다. 내 입에서 저절로 배어나온 것이 '말(언어)'가 사고를 낳고, 사고가 사상을 낳는다... 라는 표현이다.


불분명한 어휘와 사고는 결국 불확실하거나 모순된 논리를 만들게 된다. 그렇기에 정확한 어휘 구사가 좋은 소프트웨어를 설계하고 개발하는데 큰 밑거름이라고 여기게 되었다. 사람마다 상황에 따라 하나의 단어를 다른 의미로 사용할 수 있다. 그것을 완벽히 통제할 수 없거니와 그래서도 안된다. 다만, 하나의 팀으로 움직일 때는 하나의 프로젝트 안에서는 하나의 단어에 단 하나의 의미를 부여해야 한다. 이러한 철학은 프로젝트 내에서 용어나 어휘에 대해서 만큼은 토론과 자의적인 해석을 철저히 금하는 지독한 결벽주의를 낳기도 한다. 허나, 소프트웨어를 제대로 구현하기 위해서는 이러한 비인간적(?) 처사가 때로는 옳다고 생각한다.


소프트웨어는 분명 자유로운 사고 덕분에 발전한다. 하지만, 개개인의 자유로운 사고가 무질서하게 뒤엉킬 때 수많은 버그와 장애 그리고 품질 저하가 발생하는 것도 분명한 현실이다. 이에 대해 내가 생각하는 유일한 통제 수단은 프로젝트 팀(공간)과 일정(시간) 내에서의 '통제된 용어 해석과 사고, 그리고 사상(원칙)'이 필요하다는 것이다.


오해하지 말아야 하는 것은 개인의 역량과 자유를 제한하는 것이 아니라 전체의 목표를 위해 '자율에 따라 능동적으로 감수'해야 한다는 것이다. 팀원 구성원 다수의 이해와 눈높이가 다른 상태에서 단지 의사결정권자가 독단적으로 팀원의 경험과 인식에 맞지 않는 용어를 선택하는 것은 엄청한 부작용을 불러오게 된다. 인간은 자신이 스스로 선택했다고 여기지 않는 상황에 대해서는 본능적으로 책임을 회피하려 들게 마련이다. 좋은 코드는 늘 프로그래머의 적극적인 자세에서 나오기 마련이다. 억지로 행동을 통제한들 좋은 - 가독성, 성능, 재활용성 - 코드가 생산되기는 어렵다. 인간이라는 '코딩 머신'은 단지 '밥과 술'로 움직이는 것이 아니라, '감성과 공감'이라는 윤활유를 적당히 뿌려줘야 하는 까다로운 엔진이라는 말이다.


Posted by 善 곽중선
2015.02.20 13:07

인간이 완벽하지 못하다는 증거는 무수히 많지만... 소프트웨어 분야에 한정해서 보더라도 재밋는 증거라고 할까, 사례가 많다. 사이버 세계의 연금술사라고 할 수 있는 프로그래밍 언어의 설계자들이 새로운 개념과 기법을 만드는 순간에는 그것이 새롭고 기존의 문제를 깔끔하게 해결해 줄 것처럼 느껴진다. 그리고 많은 추종자들이 진리를 설파하며 기존 방법론을 과거의 잔재라며 공격한다. 허나, 새로운 연금술로 만들어낸 기술도 시간이 지나면 문제점이 드러나기 마련이다. 객체지량 언어에서 가장 큰 문제가 되어버린 기법은 가장 강력한(?) 재사용과 유연함을 얻게 해준 것처럼 느껴졌던 클래스 상속과 다형성이다. 


이제는 이러한 기법을 다시 돌아보고 버리려는 움직임이 활발히 벌어지고 있다. 프로그래밍 언어의 설계자 분들은 완벽한 사람도 아니고 그저 새로운 시도를 해보는 선구자들일 뿐이다. 새로운 시도가 실무에 적용되고 많은 시행착오를 거치며 살아남는 것들과 폐기되는 개념들이 나타난다. 어쩌면 다윈 선생의 적응에 의한 진화론에 맞다아 있는데, 우리가 늘 새로운 기술들을 공부하고 게을러지지 않아야 할 이유기 여기에 있다.

Posted by 善 곽중선
2015.02.20 13:02
  • 내 첫사랑과 마지막 사랑에 대한 이야기는 세상 그 누구도 모른다. 지난 추억에 대해 누군가 묻고 내가 서슴없이 미화하거나, 악몽이라 말한들 그것이 진실인지는 아무도 알 수 없다.

  •  데카르트는 '나는 생각한다, 고로 존재한다'고 말했다는데, 존재 증명이라 하기 보다는 자아 성찰의 방법론이라 생각하는 편이다.

  • 인간이 객관을 인식하는 방법은 나 그리고 대화 상대 뿐만 아니라, 제 3자의 증언 혹은 동의를 구하는 것이리라.

  • 구글의 페이지 랭크(page rank)가 이전의 검색엔진에 비해 더 나은 신뢰 혹은 가치를 얻게 된 것도 '웹 페이지'에 대한 참조 횟수를 중요한 척도로 삼은 것인데, 결과적으로 데이터 자체보다 그것의 가치를 판단하는 인간의 판단을 더 중시한 것이다.

  •  기술이 인간에게 기여하기 위해서는 인간의 행동 양식이나, 사고를 바탕으로 만들어져 한다. 기술을 공부하는 사람이 인문학 혹은 인간 자체에 대해 공부해야 하는 이유가 여기에 있다.


Posted by 善 곽중선