Skip to main content

사라진 즐거움을 찾아주시겠습니까?

며칠전에 소프트웨어 컨플릭트 2.0라는 책을 읽었습니다. ((로버트 L. 클래스)) 내용들이 다 유익했지만 특히 다음 장이 기억에 남네요.

사라진 즐거움을 찾아주시겠습니까?

이 장은 왜 예전에는 소프트웨어 개발이 재미있었는데 시간이 흐를수록 그렇지 않은가에 대한 내용입니다. 저자가 생각한 이유는 다음과 같았습니다.


  1. 고용주가 30년 경력 개발자를 너무나도 귀중하게 여긴 나머지 프로그래밍을 맡기지 않는다.

  2. 프로그래머가 지쳐 나가 떨어진다.

  3. 나이를 먹을수록 꼬장꼬장하게 변한다.



그런데 이 에세이를 읽은 독자가 아래와 같은 답장을 써서 보냈다네요. :-)

"엎질러진 물은 담을 수 없다"는 옛말이 있듯이, 꿈도 꾸지 마세요. 현실을 직시합시다. 업계는 우리 같은 늙은이를 반기지도 않는데, 우리는 몸값이 너무 비쌉니다. 또한 우리가 봉급을 적게 받아도 좋다고 말하면, 업계 사람들은 우리 실력이 떨어졌다고 여깁니다. 어느 쪽이든 지는 경기이므로 불가피한 현실을 받아 들여야만 하겠죠."

.
.
.

한해씩 나이를 먹다 보니 저런 얘기가 남의 얘기로만 들리진 않더군요. 그나마 책의 저자는 자신이 관리직으로 갈지 개발직으로 갈지 결정할 수 있어서 학계로 가기 전까지 개발직에 끝까지 남았다고 합니다. 저도 언제까지나 개발직에 남기를 원하지만 우리나라에서도 저런 선택이 가능할진 모르겠네요. 물론 제 옆의 동료들만 보더라도 진심으로 프로그래밍을 좋아하는 사람이 아니면 빨리 진급해서 코딩하고 디버깅하는 저주받은(?) 작업을 안했으면 하는 사람들이 있습니다. 위 리스트의 2번에 해당하는 사람들이죠.

모 SI 업체에 근무하는 마눌님의 얘기를 들어보니 과장쯤 되면 더 이상 그사람이 코딩하고 있어서는 인건비가 나오지 않는다고 얘기하더군요. 결국 코딩같은 단순한 작업은 아무나 할 수 있다는 생각을 가지고 있는거겠죠. ((왜 사람들은 Code Complete를 읽지 않는걸까요? :-( ))

그래도 마눌님이 다니는 회사는 나름 S/W 업체라 그런지 관리직군과 개발직군중에 career path를 선택할 수 있다더군요. 개발직군들에게는 특정 기술을 깊이 파도록 유도해서 그 기술의 전문가로 키우는 제도인 것 같습니다.

그런데 정말 코딩이 그렇게 아무나 해도 되는 걸까요? 그 많은 요구 사항 분석과 설계와 문서들은 결국 다 코드를 만들기 위해선데 말이죠. ((역시 Code Complete에 있는 내용!)) 굳이 무슨 연구 결과들을 참고 하지 않더라도 제 경험에 따르면 잘하는 사람과 못하는 사람의 결과는 수배에서 수십배 차이가 나는 것 같습니다. 굳이 찾아보자면 생산성이 minus인 사람들도 있죠. (제발 저 사람은 코딩을 안했으면 하고 바라게 됩니다. 근데 혹시 이런걸 원했던 걸까요? :-? 참... 그리고 저희 팀엔 없어요. ;-) )

능력있고 경험있는 사람들이 관리직으로 가진 않는다 해도 코딩은 안하고 설계만 한다는 것도 문제가 있습니다. 설계만 보고 일대일로 코드를 만들어낼 수 없다면 결국 코드의 질은 코더에 많이 좌우될텐데 말이죠. 너무 코딩을 천시하는 경향이 있는 것 같습니다.

게다가 코딩이 제일 재밌는 단계지 않나요. (제가 원하는게 바로 이겁니다! 저한테 계속 코딩을 할 수 있게 해주세요~ ;-) )

한가지 더... 설계와 구현, 두 단계를 다른 사람이 혹은 다른 팀에서 하게 되면 둘 사이엔 의견 mismatch가 생길 수 밖에 없는 것 같습니다. 구현팀에선 설계를 정확히 이해하지 못하고 구현하는 부분이 생기게 되고 설계팀에선 자신들의 우아한 설계를 반영하지 못했다고 불평하고요. 게다가 설계에는 불가피하게 구현상의 detail이 빠질 수 밖에 없습니다. 둘 사이에 이런 어긋남이 쌓이게 되면 서로 신뢰가 떨어지고 결국은 서로 제 갈길 가는 형태가 되곤 하는 것이죠. ("넌 떠들어라. 난 모르겠다." - 구현팀, "난 완벽하다. 잘못되면 다 너네 잘못이다." - 설계팀)

따라서 설계와 구현은 같은 사람이 아니면 적어도 같은 팀에서 해야 하지 않을까 합니다.

.
.
.


저희 회사도 작년에 career path를 관리직군과 개발직군으로 나눠야 하나 같은 설문 조사를 한 적이 있는데 이후로 소식이 없네요. 한 십년쯤 지나면 선택할 수 있게 될지도 모르겠어요. 그나저나 사라져 가는 제 즐거움을 지키려면 어떻게 해야 할까요? :-|

Comments

  1. SI업체에서는 코딩을 폄하(?)할 수 밖에 없는 것 같습니다. -ㅅ- (그러면 안되지만요!)
    패키지(?)의 입장에선 많이 다르지요.

    (다행히 제가 있는 곳은 패키지 회사.. 에헤)

    ReplyDelete
  2. 코딩이 회사에 직접적인 금전적 이익을 가져다 주지 않는경우에 윗분들이 값을 좀 낮춰 보는 것 같습니다. 그리고 나 외에 대체 가능한 코더가 존재할 때는 값이 더 낮아지겠죠 ^^
    또한 코딩이라는게 특이하게도 초고수가 인공지능을 가미한 객체지향으로 짜든 쌩초보가 스크립트로 구조적으로 짜든 목적에 도달하는 방법만 알고있다면 그럭저럭 굴러가는 프로그램을 짤 수 있다는겁니다. 제가 로봇 분야에 있는데, 예를 들어보자면, 로봇이 장애물을 피해서 목적지까지 이동하는 코딩을 해야할 때 연구원들이 난관에서 헤어나지 못하는 이유가 훌륭한 코딩 기술보다는 주로 적절한 알고리즘을 구현하지 못하였기때문입니다.

    ReplyDelete
  3. 까막님/ 네, SI업체들은 수입이 전부 인건비에서 나오는 것이라 더 그런거 같아요. 그래도 까막님은 좋은 환경에 계시는 듯 하네요. :-)

    야옹/ (뭘 존댓말씩이나. 어색하게... -_-+) 그런 코더가 짠 코드가 그럭저럭 굴러간다면 1) 좋은 framework 위에서 시작했거나 (예를 들어 MFC만 있으면 누구든 적당히 굴러가는 Windows GUI 프로그램을 할 수 있는 것처럼. 이는 기본적으로 MFC가 Doc/View라는 나름 잘 짜여진 구조를 가지고 있기 때문이지.) 2) 규모가 크지 않은 경우가 아닐까?
    로봇 분야는 잘은 모르지만 이전의 단순하던 로봇에서 점점 복잡해질수록 프로젝트에서 소프트웨어가 차지하는 비중이 커질텐데 그럼 당연히 하드웨어 전문가나 알고리즘만 필요한 것이 아니라 소프트웨어 공학도 필요할듯... 그런데 문제는 소프트웨어 공학이 더 필요한 분야에서도 아직 그렇지 못하다는거지... -_-;

    ReplyDelete

Post a Comment

Popular posts from this blog

1의 개수 세기 - 해답

벌써 어제 말한 내일이 되었는데 답을 주신 분이 아무도 없어서 좀 뻘쭘하네요. :-P 그리고 어제 문제에 O(1)이라고 적었는데 엄밀히 얘기하자면 O(log 10 n)이라고 적었어야 했네요. 죄송합니다. ... 문제를 잠시 생각해보면 1~n까지의 수들 중 1의 개수를 얻기 위해서는 해당 숫자 n의 각 자리의 1의 개수가 모두 몇개나 될지를 구해서 더하면 된다는 사실을 알 수 있습니다. 예를 들어 13이라는 수를 생각해 보면 1~13까지의 수에서 1의 자리에는 1이 모두 몇개나 되는지와 10의 자리에는 모두 몇개나 되는지를 구해 이 값을 더하면 됩니다. 먼저 1의 자리를 생각해 보면 1, 11의 두 개가 있으며 10의 자리의 경우, 10, 11, 12, 13의 네 개가 있습니다. 따라서 2+4=6이라는 값을 구할 수 있습니다. 이번엔 234라는 수에서 10의 자리를 예로 들어 살펴 보겠습니다. 1~234라는 수들 중 10의 자리에 1이 들어가는 수는 10, 11, ..., 19, 110, 111, ... 119, 210, 211, ..., 219들로 모두 30개가 있음을 알 수 있습니다. 이 규칙들을 보면 해당 자리수의 1의 개수를 구하는 공식을 만들 수 있습니다. 234의 10의 자리에 해당하는 1의 개수는 ((234/100)+1)*10이 됩니다. 여기서 +1은 해당 자리수의 수가 0이 아닌 경우에만 더해집니다. 예를 들어 204라면 ((204/100)+0)*10으로 30개가 아닌 20개가 됩니다. 이런 방식으로 234의 각 자리수의 1의 개수를 구하면 1의 자리에 해당하는 1의 개수는 ((234/10)+1)*1=24개가 되고 100의 자리에 해당하는 개수는 ((234/1000)+1)*100=100이 됩니다. 이들 세 수를 모두 합하면 24+30+100=154개가 됩니다. 한가지 추가로 생각해야 할 점은 제일 큰 자리의 수가 1인 경우 위의 공식이 아닌 다른 공식이 필요하다는 점입니다. 예를 들어 123에서 100의 자리에 해당하는 1의 개수는 ((123/1

std::map에 insert하기

얼마전 회사 동료가 refactoring한 코드를 열심히 revert하고 있어서 물어보니 다음과 같은 문제였습니다. 원래 코드와 refactoring한 코드는 다음과 같더군요. nvp[name] = value; // original code nvp.insert(make_pair(name, value)); // refactored 아시겠지만 위의 두 라인은 전혀 다른 기능을 하죠. C++03에 보면 각각 다음과 같이 설명되어 있습니다. 23.1.2/7 Associative containers a_uniq.insert(t): pair<iterator, bool> inserts t if and only if there is no element in the container with key equivalent to the key of t. The bool component of the returned pair indicates whether the insertion takes place and the iterator component of the pair points to the element with key equivalent to the key of t. 23.3.1.2/1 map element access [lib.map.access] T& operator[](const key_type& x); Returns: (*((insert(make_pair(x, T()))).first)).second. 원래 코드는 매번 새 값으로 이전 값을 overwrite했지만 새 코드는 이전에 키가 존재하면 새값으로 overwrite하지 않습니다. 따라서 원래 기능이 제대로 동작하지 않게 된것이죠. 그래서 물어봤죠. "왜 이렇게 했어?" "insert가 성능이 더 좋다 그래서 했지." :-? 사실 Fowler 아저씨는 Refactoring 책에서 refactoring은 성능을 optimizing하기 위한 것이 아니다라

C++ of the Day #9 - Boost.Python 사용하기 #1

Python 은 가장 인기있는 interpret 언어중의 하나입니다. Python의 장점 중 하나는 C/C++ 모듈과 쉽게 연동할 수 있다는 점입니다. 물론 손으로 일일히 wrapper를 만드는 것은 손이 많이 가고 에러를 만들수 있는 작업이나 SWIG 등과 같은 도구를 사용하면 쉽게 python 모듈을 만들 수 있습니다. Boost.Python 은 이런 SWIG와 같이 python 모듈을 쉽게 만들 수 있도록 도와주는 라이브러리로 순수 C++만을 사용한다는 점이 SWIG와 다른 점입니다. 그리고 개인적으로는 Boost 라이브러리에 포함되어 있는 것들이 왠지 좀 더 믿음직스러워서... :-) 이번 글에서는 Boost.Python 문서에 나와 있는 예제 를 가지고 간단하게 python 모듈을 만드는 방법에 대해서 알아보겠습니다. Requirements 리눅스 이 글에서는 리눅스 환경에서의 사용 방법을 설명한다. Boost.Python 라이브러리 (1.33.1) Boost 라이브러리를 다운로드받아 아래와 유사한 명령으로 라이브러리를 빌드한다. bjam -sTOOLS=gcc -with-python install bjam의 --prefix 옵션으로 라이브러리가 설치될 위치를 변경할 수 있다. Python 라이브러리 (2.4.3) Python을 다운로드 받아 빌드하여 설치한다. 위의 경우와 유사하게 configure의 --prefix 옵션으로 설치될 위치를 변경할 수 있다. Write C++ Code 다음과 같이 코드를 작성한다. // greet.cpp #include <stdexcept> char const* greet(unsigned x) { static char const* const msgs[] = { "hello", "Boost.Python", "world!" }; if (x > 2) throw std::range_error("