읽은 기록

The Psychology of Computer Programming

2024 아카데미 컨퍼런스 1회차 책이다.

쉽게 프로그래밍 분야의 아주 고전책으로 사례는 정말 과거의 이야기지만, 본질은 변하지 않는다는 것을 알려준 책이다. 프로그래밍의 다양한 분야에 대해서 아주 깊게 다루기 때문에 필요에 의해 찾아보기도 좋다.

한번은 꼭 읽어봤으면 하는 책이고 나중에 꼭 다시 볼 생각이다.

1부 인간 행위로 보는 프로그래밍

중요한 것은 질문을 멈추지 않는 것이다.
호기심에는 그 나름의 존재 이유가 있다.
영원과 인생 그리고 신비한 현실의 구조가 주는 불가사의를 생각해 보면 우리는 경외심을 느낄 수밖에 없다.
이러한 불가사의를 매일 조금씩 이해하려고 노력하는 것만으로 충분하다.
절대로 신성한 호기심을 잃지 말라.
아인슈타인

컴퓨터 프로그래밍은 인간의 행위다.

수년에 걸쳐 경영자들은 자신의 사업에서 프로그래머라는 요소를 배제하기 위해 막대한 자금을 솓아 부었다.

1장 프로그램 읽기

  • 왜 경영자가 프로그램을 읽을 수 있어야 하는가?

프로그래머로써 자신이 맡은 업무가 아니더라도 프로그램을 읽는 것은 프로그래밍을 배운다는 의미에서 그다지 나쁜 일은 아니다.

과거엔 프로그래밍 환경이 좋지 못했기 때문에 실습뿐만 아니라 학습(읽기)을 통해서도 능력을 길렀다.

하지만 시대가 변함에 따라 컴퓨터와 씨름하느라 균형이 무너진다.

프로그래머라면 다른 사람의 프로그램을 읽어서 뭔가를 얻을 수 있다.

나쁜 예제라면 반면교사로 좋은 예제라면 프로그램의 흐름을 알거나 자신이 모르고 있는 부분을 명확하게 알 수 있을 것이다.

글쓰기에서도 badcase를 참고하는게 좋을 수 있다고 한다.

프로그램을 읽을 때 각 부분의 발단으로 구성된 개념적인 프레임워크를 토대로 읽어야 한다.

즉, 코드를 한 줄 만날 때마다 “이 코드가 왜 여기에 있을까?”를 생각하는 것이다.

문서화되지 않고 당시에 상황을 해결하기 위해 작성된 프로그램은 큰 단점이다.

기계의 한계

다른 협업자(미래의 나)가 오용하거나 이를 한계로 인식하지 않고 단점을 사실로 인정해버리는 경향이 있다.

언어적인 한계

언어의 한계로는 하이 레벨 언어를 사용하다 보면 하드웨어의 특정 기능을 사용할 수 없게 된다는 점이 있다.

언어적인 한계로 필요 이상의 제약이 발생하고 이 때문에 코드의 덩치는 커진다.

그러나 이런 제약이 사라지기 전까지 제약으로 인식되지 못할 수도 있다.

교외에 나가서야 도시의 공기가 혼탁했다는 사실을 깨닫게 되는 것처럼 말이다.

따라서 언어가 생겨남에 따라 현재에는 인식하지 못하는 새로운 한계가 드러날 수도 있다.

프로그래머의 한계

프로그래머는 사용하는 컴퓨터와 언어, 프로그래밍에 대한 지식에 대한 부족으로 많은 코드를 쓸데없이 추가할 수 있다.

특정 알고리즘에 대해 모르거나, 충분히 이해할 능력이 안 될 수도 있다.

역사의 흔적

해당 프로그램의 개발 역사 때문에 여전히 존재하는 문제점들을 발견하는 경우도 있다.

명세

명세는 프로그램, 프로그래머와 함께 진화한다.

프로그램을 작성하는 것은 일종의 학습이다.

프로그램이 하는 일이 우리가 그 프로그램에게 원했던 바로 그것이길 바란다. (프로그램은 동작헤야 한다.)

요약

어떤 프로그램이 현재의 모습을 갖게 된 데에는 다 이유가 있다.

코드를 세심히 읽기보다는 그저 훑기만 하기 때문에 그 이유를 모두 알아차릴 수는 없겠지만 읽다보면 기계, 언어, 프로그래머의 한계로 그런 모습이 되었거나 혹은 당시에 존재했던 외부 조건(사건), 주어진 명세 때문에 그렇게 작성되었음을 알 수 있다.

최종 산출물에 포함된 코드에는 각각 나름의 이유가 있고, 그 이유에는 심리적인 면이 있다.

  • 콘웨이의 법칙

논의사항

  • 작업중인 프로젝트나 회사 코드 말고 다른 외부의 달인, 전문가가 작성한 코드를 많이 참고하시는 편인가요?

2장 좋은 프로그램이란 무엇인가?

프로그래밍을 인간의 행위로 연구하기 위해선 능률을 측정할 방법이 필요하다. (어떤 프로그래머가 우수한지)

프로그래밍은 단순한 인간의 행위가 아니라 복잡한 인간의 행위이기 때문에 답을 도출하기 까다롭다.

좋은 프로그램을 평가할 때 코드 자체만으로 좋다 나쁘다를 논할 수 없다.

보편적인 좋은 프로그래밍은 개개인의 사상으로 존재할 수 있지만, 사실이라고 해도 좋은 프로그램의 존재를 말할 수 없다.

즉, 프로그램을 개발하며 일어난 주변 환경과 실행 환경을 전혀 고려하지 않은 채 프로그램의 점수를 딱 정할 수 없다는 것

프로그램 평가 기준에서 그 프로그램이 실행될 기계와 컴파일러, 비용 환경 등을 고려하지 않을 수 없다.

프로그램 개발은 계획한 기간 안에 끝냈는가?, 개발 비용이 얼마나 들었는가? 주어진 환경 명세서를 만족 시키는 가 등등

단지 코드만 보고서는 이런 요소를 알 수 없다.

상대적인 척도도 불가능하다.

최고의 프로그램은 동작하며 명서세에 부합하는 프로그램이다.

요구 명세

프로그램에 요구하는 조건 중 가장 먼저 꼽히는 것은 정확성이다.

프로그램이 작동하지 않는 상황에서 효율성이나 적응성, 개발 비용 등의 다른 척도는 전혀 의미가 없다.

세상에 완벽한 프로그램은 절대 없다.

따라서 프로그램이 주어진 요구 명세를 얼마나 만족시키느냐 즉, 얼마나 잘 작동하느냐가 문제가 되는 것이다.

사용자 한 명을 위한 프로그램과 진정한 소프트웨어 사이에는 엄연한 차이가 있다.

사용자가 여럿이면 요구 명세도 여러 벌이 된다.

일정

요구 명세를 만족시키는가의 문제를 차지한다 해도 효율성이 최우선의 문제가 되지 않는다.

프로그래밍에서 계속 반복되는 문제는 일정을 맞추는 일이다. (마라톤)

개발 기간 중 크런치가 위험한 이유

적응성

대다수의 프로그램들은 일정 기간 동안 생명을 유지한다.

그리고 그 생명 주기 동안 대부분의 프로그램은 수정을 겪는다.

그렇다면 왜 사람들은 원래 작성된 코드를 버리고 처음부터 몽땅 새로 작성해야겠다고 결정하는 상황이 많은 것일까?

  • 피셔의 기본정리
    • 한 유전자 시스템이 특정 환경에 많이 적응되어 있을수록 다른 새로운 환경에 적응하기는 더 어렵다.

프로그램이 효율적으로 동작하게 만들려면 주어진 문제와 프로그램을 실행할 기계의 특성을 잘 활용해야 한다.

기계의 구조를 무시하면 프로그램은 잠재적으로 성능 면에서 큰 손해를 보게 되고, 문제의 특성을 잘 활용하면 프로그램을 더 작고 빠르게 만들 수 있다.

효율성을 추구하면 보통은 코드가 빡빡해져서 수정하기 어렵게 된다.

고수준 언어로 작업하다가 프로그램을 좀 더 효율적으로 만들려고 기계어로 내려가는 일도 가끔 있다.

이는 프로그램을 고수준 언어로 작성하는 이점 중 하나를 포기하는 것이다.

그리고 그렇게 하면 특정 기계에 얽매일 뿐 아니라, 당시의 만족스럽지 못한 프로그램 구현 상태에도 종속되는 것이다.

거꾸로, 일반적이고 수정하기 쉬운 프로그램을 요구하는 관리자들도 나중에는 프로그램이 느리거나 너무 크다고 불평하곤 한다.

우리는 이 사이에서 균형잡기를 해야 한다.

효율성

프로그램의 진정한 효율성은 언뜻 생각하기와 달리 쉽게 측정할 수 없다.

일단, 컴퓨터에서 실행시키는 데 필요한시간만이 효율성의 전부가 아니다.

실행 전후에 드는 시간이 컴퓨터의 실행 시간에 영향을 미칠 수 있다.

언어의 사소한 차이로도 컴파일러의 효율성은 크게 달라질 수 있다.

컴퓨터가 소비하는 시간만이 비용의 모든 요소인 것은 아니다.

사람이 소비하는 시간도 비용이다.

여기서 트레이드 오프 발생 앞서 다른 고수준 언어와 저수준 언어 그리고 효율성 측면의 생각

단순히 컴퓨터상의 실행 시간만 줄인다고 능사는 아닌 것이다.

결론적으로 컴퓨팅에서 효율성은 점점 더 애매해지고 있다.

현대에는 언어가 더 고수준에 가까워짐에 따라 최적화는 좀 나중의 문제로 보인다.

시간이 지날수록 효율성보다 효용성이 더 증가할 것이다.

요약

좋은 프로그램이란 무엇인가라는 물음에 다음과 같이 답할 수 있다.

  • 프로그램이 동작하는가? (추가)
  • 프로그램이 요구 명세서에 부합하는가?
  • 일정에 맞춰 개발하였는가?
  • 환경이 변한다면 그에 맞춰 프로그램을 수정할 수 있는가?
  • 프로그램이 얼마나 효율적인가?

코드의 품질을 평가하는 방법을 결정하는 새로운 요소 가운데 가장 큰 것은 경제적 요소이다.

이는 게임업계에서도 많이 증명된다.

실제 코드의 구조가 좋지 못하더라도 100만장을 판 인디게임이라면 성공한 게임이다.

고객을 만족시키고 소프트웨어적으로 성공했기 때문이다. (게임은 상품)

논의사항

  • 스스로 생각하시는 프로그래머로서의 성공, 최종 목표는 어디인가요?

3장 프로그래밍이란 행위를 연구할 방법은 무엇인가?

앞서 지적한 바와 같이, 프로그래밍은 엄연히 인간 행위(복잡한)의 한 형태임에도 그런 관점에서 프로그래밍을 연구한 사람은 거의 없다.

인간의 지식은 필연적으로 불완전하다.

우리는 앞으로 무엇을 알게 될지 그리고 무엇을 절대 알 수 없을지를 미리 알지 못한다.

그러나 이것 하나는 확실하다.

알려고 시도하지 않는다면 절대 알 수 없을 것이다.

“중요한 것은 질문을 멈추지 않는 것이다.”

프로그래밍은 인간 행위이므로 인간행동학을 참고하는 것이 현명해 보인다.

내성법

현대 인간행동학에서는 내성법을 비과학적인 것으로 취급하지만, 내성법은 인간행동 연구에서 항상 기초가 되어 왔다.

내성법을 통해 프로그래밍에서 뭘 관찰할 수 있을까?

예제와 같이 한 문장의 적절한 길이, 자료 구조의 선택, 프로그램 내 코드의 배치, 괄호의 사용, 컴파일러와 실행 모니터링 기능의 설계, 프로그래밍 교수법 또는 학습 기술 등등.

모두 내성법 아니고서는 인지하기 힘든 문제다.

그러나 프로그래머는 매일 부딪히는 이런 문제를 단순히 버그라고 생각한다.

내성법을 실천하지 않는다면 그 버그는 결국 그들을 잡아먹을 것이다.

  • 사람의 정신은 중첩된 괄혼가 다섯 단계를 넘으면 다룰 수 없다.
  • 컴파일러의 진단 기능이 좀 더 명확해져야 한다.
  • PL/1의 정밀도 규칙은 너무 복잡해서 사용하기 어렵다.

위 같은 명제를 내성법을 통해 써봤자 법칙이 될리 없다.

어떤 명제가 법칙이 되기 위해서는 그 적용 한계가 어디인지까지 밝혀야 한다.

모든 법칙에는 한계가 있기 때문이다.

사실 보통 그 한계가 법칙 자체보다 더 중요하다.

그리고 법칙의 적용 한계는 다양한 경우를 조사해야 알 수 있다.

따라서 내성법 없이 조사한 결과는 빈약하겠지만, 조사가 뒷받침되지 않은 내성법의 결과는 그 가치를 의심받을 것이다.

관찰

내성법의 결과를 검증하는 방법 가운데 사람들이 자신이 어떻게 행동할것이라 생각하느냐가 아닌 그들의 실제 행동을 관찰하는 방법이 있다.

또는, 관찰의 결과로 새로운 논제가 생겨날 수도 있다.

관찰의 두번 째 문제점은 관찰은 관찰일 뿐이라는 것이다.

관찰을 할 때에는 매우 신중해야 한다. 프로그래밍은 극도로 복잡한 행위이기 때문이다. (각 상황은 여러 가지 면에서 차이가 있기 때문이다.)

세번 째 문제점은 관찰자와 피관찰자 사이에 생기는 간섭 현상이다. (불확정성 원리의 일종이다.)

그런 현상을 만드는 원인은 관찰 행위 그 자체였던 것이다.

이런 현상을 설명하는 호손 효과라는 이론이 있다.

피험자들이 실험에 참가하고 있다는 사실을 의식해서 평소와 다른 행동을 함으로써 결과에 영향을 미치는 현상을 말한다.

관찰자와 피관찰자 사이의 간섭 현상은 비단 산업심리학에서만 일어나는 것은 아닌 인간의 행동을 연구하는 모든 과학 분야에서 문제가 된다.

실제 관찰자들은 철저히 투명인간이되려고 노력하고 이를 통해 은밀하게 관찰한다.

컴퓨터 분야에서 사용하는 은밀한 관찰법으로는 사용자의 행동을 컴퓨터를 통해 직접 기록하는 것이다.

컴퓨터의 로그는 매우 자세한 수준까지 기록되기 때문에 그 자료를 통해 사용자 개개인까지도 연구할 수 있다. (통계)

실험

관찰해서 생긴 자료가 지나치게 방대하기 때문에 소요되는 비용을 줄이는 방법 가운데 실험 설계가 있다.

실험을 이용하면 더 적은 자료로도 연구하려는 행동에 관한 더 많은 정보를 얻을 수 있다.

그러나 실험 내재하는 가장 큰 문제은 실험이 지나치게 정제되어 가장 흥미로운 자료를 얻는 데 실패할 수도 있는다는 점이다.

너무 제약되어 피험자가 자연스러운 상황에서는 절대 하지 않을 행동을 할 수 있다.

다른 문제로는 실제 배치 시스템과 다를 수 있다던가 비용적인 문제가 있을 수 있다.

보통 프로그래밍을 사회적 행위가 아닌 개인 행위로 취급한다.

그러나 프로그래밍에 관한 연구는 프로그래머 그룹 차원에서 행하는 것이 적절하다는 증거가 여럿 있다.

개인 차원이 중요하지 않다는 뜻은 아니지만, 일반적인 프로그래머는 작업 시간 중 3분의 2를 다른 사람과 협업하는 데 소비한다.

심리학의 측정법

“프로그래밍을 몇 년이나 했는지”를 경험을 측정하는 척도로 삼는 것은 프로그래밍 심리학을 연구할 때 부딪히는 많은 측정 문제 중 하나에 불과하다.

인간의 행동을 관찰하거나 연구하는 과정에서 측정해야 할지도 모르는 항목이 수백만까지는 아니더라도 족히 수천 개는 된다.

이러한 많은 항목이 문제가 된다. (아직 심리학, 인간행동학이 중분히 성숙하지 못했기 때문)

그러나 인간의 행동을 연구할 때는 그렇게 단순하게 할 수가 없다.

심리학의 주제는 측정할 수 있는 것으로 정하는 게 아니라 알고 싶은 것으로 정한다. (따라서 가능한 많은 요소를 측정)

그 중 몇 개만이라도 주어진 문제를 꿰뚫는 통찰을 얻는 데 도움이 되길 바라면서 말이다.

실제로, 태어난 달이나 계절이 어떤 심리적 또는 물리적 변수와 상관관계가 있다는 취지로 시작한 연구가 있다. (통계적 사주 관점)

민간 지식은 통찰을 얻는 한 방편이 될 수 있다.

또 다른 방편이 있다면, 현재 다른 목적을 위해 사용되는 수단을 빌리는 것이다. (IQ검사 등)

그러나 가장 표준적인 과정은 역시 그 반대 방향이다. (문제에서 수단으로)

연구 대상을 잘 알지 못한다면 무엇을 측정해야 할지 미리 알 수 없는 노릇이다.

프로그래밍 심리학의 현재 수준에서는 질문을 찾는 것이 주된 작업이다.

기존 심리학의 측정 수단들을 이용할 수 있다지만, 그렇다 해도 아직 그 수단들을 시험하는 것이지 주제를 직접 다루는 수준은 되지 않는다.

논외로 궁금해진 MBTI와 개발자간의 상관성이 궁금해져서 알아봤다. 실제로 조사하고 이를 통해 통계를 작성하는 경우가 많다. 한국에서도 다양한 글이 있지만 아마 외국에서는 실제로 이를 통해 통찰을 얻기도 할 것 같다. 관련글

하지만, MBTI특성이 사람의 평균 수에 비례하지 않기 때문에 경향성을 보는 것이지 이를 통해 심리학의 문제를 해결할 수는 없는 것 같다.

인간의 행동을 연구한 선배 과학자들이 이미 경험했던 함정을 인지하지 못한 상태에서 얻은 측정을 가지고 성급하게 결론을 내는 것은 누구나 지양해야 할 일이다. (마치 갈릴레이의 사고 실험)

인간행동학의 기존 연구 자료 이용

기존의 인간행동학 연구에서 우리가 배울 부분은 주로 그 방법론이다.

프로그래밍은 매우 특수하므로, 그 결과를 프로그래밍 심리학에 그대로 적용하길 바라기는 어렵다.

기존 연구 결과는 답을 얻기보다는 통찰을 얻는 데 이용해야 한다.

너무 특화된 이론에는 현혹되지 않는 것이 좋다.

프로그래밍에 해당하지 않는 상황을 전제로 한 이론이기 쉽기 때문이다.

프로그래밍에는 올바른 해답이 없기 때문에 설사 있다고 해도 피험자보다 더 올바른 해답을 알고 있다는 보장은 없다.

컴퓨터 프로그래밍에 대한 가장 유용하고 포괄적인 모델을 제시하는 사회 과학은 인류학이다.

커뮤니케이션, 사회적 구조관계이다.

확실히 프로그래밍 관련 분야에서 심리학적으로 가장 많이 활용될 수 있는 부분이 인간관계론쪽이라 생각된다.

이런 개인적, 사회적인 측면 이후에는 프로그래머의 도구를 심리학적 관점에서 검토해야 한다.

도구는 잃어버린 프로그래밍 문명을 이해하기 위해 발굴하고 연구해야 할 유물인 것이다.

마지막으로 이런 논의를 모두 성공적으로 마치고 나면, 프로그래밍에 대한 신화적인 사회 통념과 신조를 충분히 객관적인 관점에서 고찰할 수 있을 것이다.

요약

프로그래밍은 복잡다단한 행위이기 때문에 우리는 인간행동학에서 가능한 많은 방법론과 연구 결과를 차용할 필요가 있다.

그러나 그 과정에서 함정에 빠질 우려가 있으므로, 프로그래밍 심리학을 직접 연구하려 할 때에는 통상적인 함정에 미리 대비해야 한다.

주요 문제점

  • 검증 없이 내성법을 사용하는 것
  • 지나치게 한정된 대상을 관찰하는 것
  • 잘못된 변수를 측정하는 것 또는 옳은 변수를 측정하지 못하는 것
  • 관찰 대상의 행동에 개입하는 것
  • 자료는 과도하게 모으고도 정보는 충분히 얻지 못하는 것
  • 실험에 지나치게 많은 제약을 가하는 것
  • 과도하게 초보 프로그래머들만 연구 대상으로 삼는 것
  • 집단 효과와 집단 행동을 연구하지 못하는 것
  • 측정하기 쉬워서 측정하는 것
  • 검증 되지 않은 정밀도를 사용하는 것
  • 기존 연구의 결과를 적절치 못한 대상에 적용하는 것

그러나 아직 미숙한 분야에서 일어나는 최대 실수는 바로 지나친 신중함이다.

실험을 전혀 하지 않는 것보다 실험을 한 후에 실패하는 편이 더 낫다.

아마도 프로그래밍은 연구 대상으로 삼기에 너무나 복잡한 행위이기 때문에 커다란 불가사의로 남을 수밖에 없었을 것이다.

논의사항

  • 자신만의 내성법을 통한 명제가 있을까요?

2부 사회 활동으로 보는 프로그래밍

…(중략) 그 과정에서 나는 지시와 규율에 따른 행동과 상호 이해에 따른 행동의 차이를 점차 깨닫게 됐다.
목표는 수많은 의지가 모여 만드는 모진 노력으로만 성취할 수 있다.
피터 크로포트킨

프로그래머는 혼자 일하지 않는다.

1인 프로그래머와 2인 프로그래머의 차이는 단순 능률의 2배의 문제가 아니다. (3배 이상으로 늘어난다고 생각)

프로그래밍 팀이란 더 나은 제품을 만들기 위해 함께 일하는 프로그래머의 모임이다.

4장 프로그래밍 그룹

프로그래머들을 공식적인 팀 또는 프로젝트 조직화한다 해도, 그 내부에서는 비공식적인 관계들이 비구조적인 그룹에 있는 만큼이나 많이 생겨난다.

사실, 우리가 사회 심리학에서 가장 먼저 배워야 할 것은 공식 그룹과 비공식 그룹의 차이점이다.

공식 조직과 비공식 조직

프로그래머 간의 상호관계가 조직도를 있는 그대로 따라 그 좁고 단선적인 통로를 통해서만 형성된다면 프로그래밍 작업에 진척이 있을 리 없다.

트리형태가 아닌 그래프형태로 이뤄져야 한다.

공식적인 구조만이 어떤 조직 내의 유일한 구조라는 생각은 위험하다.

프로젝트에서 비공식 구조는 대부분 작업의 구조에 영향을 받아 결정된다.

그 프로젝트가 얼마나 잘 조직화되었느에 따라 조직도에 가까운 모습이 될 수도 있다.

그러나 비공식 구조는 항상 기존 공식 구조의 기능을 정정하고 보완하는 방향으로 자라난다.

현명한 상급자라면 비공식 구조를 공식화하기도 한다.

  • 여비서의 사례 (긍정적)
    • 서비스가 필요함을 깨닫게 된 관리부가 공식적인 시스템으로 사용 (B레벨)
  • 종합대학 자판기의 사례 (부정적)
    • 자판기를 원위치 시키는 대신 조교를 늘림

위 두가지 사례의 요점은 비공식적인 조직은 항상 존재하며 그것을 깊이 이해하지 않은 상태에서 바꿔 버리면 위험하다는 것이다.

그렇게 하면 원할하게 돌아가던 전체 시스템을 교란시키는 꼴이 되기 때문이다.

또한 깊이 이해하지 못했으므로 그 비공식적인 조직을 비슷한 비용의 공식적인 조직으로 대체할 수도 없을 것이다.

그런 교란 가운데 많은 경우가 물리적인 배치를 변경하여 발생한다.

물리적 환경과 사회적 조직

우리는 물리적 환경이 프로그래밍 작업의 양과 질에 영향을 끼침을 모두가 알고 있다.

소음이나 빛, 온도 등과 같은 요소가 아닌 작업 공간의 배치를 말한다.

프로그래머를 한군데 모아 놓으면 분명 중요한 이점이 생긴다.

그러나 관심을 가져야할 부분은 작업 공간의 배치가 사회적인 상호작용에 미치는 영향이다.

그 상호작용이 다시 작업 결과에 영향을 주기 때문이다. (재귀적)

  • 승강기 기사의 사례
    • 기사와 대화를 통해 유용한 정보의 전달이 있었다.

단말기 시스템의 원격에서 작업할 수 있는 측면은 어쩌면 축복이 아닌 저주일 수 있다.

1장에서 나온 내용처럼 생각하거나 정보를 나눌 기회가 줄어들고 있다.

프로그램의 오류와 프로그래머의 자아

프로그래밍은 개인의 행위인 동시에 사회적 상호작용을 많이 요구한다.

프로그래머는 대부분 고립된 장소에서 혼자 일하는 편을 더 선호하는 경우가 많다. (대다수)

물론 프로그래밍 업무에서 상당 부분이 홀로 그리고 창조적으로 해야 하는 것이므로 그런 프로그래머를 선택하는 것이 좋다.

그러나 종종 이런 고립성이 너무 지나쳐 사람들에게서 고립되고 자신의 프로그램에 애착을 두는 경우가 있다.

자신이 작성한 프로그램을 자신의 것으로 여기는 데 무슨 문제가 있을까?

실제 작가, 건축가, 프로그래머는 사람에게 존쟁을 받고 실력이 떨어지는 사람들은 그 작품을 모방하여 발전하곤 한다.

하지만 사람들은 프로그램을 읽지 않기 때문에 어떤 프로그래머를 흠모한다고 해서 그 프로그래머의 작품을 모방하게 되지 않는다.

단지 매너리즘을 부추길 뿐이다.

모두 어떤 화가처럼 보이는 방법은 알고 있지만, 그 화가처럼 그리는 방법을 아는 사람은 거의 없다.

누구의 것이냐를 중시하는 프로그래밍에서 나타나는 실질적인 문제점에는 또 다른 원인이 있다.

어떤 그림이나 소설, 건물이 열등하다는 생각은 취향의 문제다.

그러나 어떤 프로그램이 열등하다는 생각은 적어도 잠재적으로 객관적인 증명 또는 반증이 가능하다.(좋은 프로그램을 정의하기가 어렵다는 사실은 자치하고)

최소한 우리는 프로그램을 컴퓨터에서 실행해 나오는 결과를 볼 수 있다.

화가의 경우에 따라 비판을 수용하지 않을 수도 있다. 그러나 프로그래머가 컴퓨터의 판단을 무시할 수 있을까?

표면상 컴퓨터의 판단은 의심할 여지가 없다.

그렇다면 자기 프로그램에 대한 프로그래머의 애착은 자화상에 심각한 손상을 남길 수 있다.

컴퓨터가 자신의 프로그램에 오류가 있다는 결과를 내면, 프로그래머는 이렇게 생각할 것이다.

“이 프로그램에는 결함이 있어. 그런데 이 프로그램은 내 일부야. 나의 외연이란 말이지. 심지어 내 이름도 물려받았어. 그러니까 결함은 나에게 있어.”

자신의 프로그램이 자아의 외연이라고 진심으로 믿는 프로그래머는 프로그램에 있는 모든 오류를 찾아내려 하지는 않을 것이다.

오히려 그 프로그램의 정확성을 증명하려 노력할 것이다.

좋은 프로그램을 만들기 위해서는 확실한 반증이 있음에도 자신의 프로그램은 부정확하다고 믿으려는 완전히 정상적인 사람의 성향에 대해 뭔가 조치를 취해야 한다.

비자아적 프로그래밍

직접적인 공격이 이 문제에 대한 해결책이 될 수는 없다.

공격은 언제나 방어를 부르고, 그런 방어 자세는 우리가 없애려 노력해야 할 대상이기 때문이다.

자아 문제는 사회적 환경과 더불어 프로그래머들의 가치 체계를 재구성함으로 극복해야 한다.

  • 빌의 사례
    • 남이 오류를 찾는 것은 그에 대한 개인적인 공격이 아니라 코드를 개선하기 위함이었다.
    • 비자아적 프로그래밍이 더 널리 실천되지 않은 이유 (그룹이 희귀하게 여겨짐)
      • 협업을 근간으로 방식 자체를 성공적이라는 지식 자체를 가지고 마치 그들만의 지적소유권이 있는 정보라고 생각한다.
      • 이런 방식으로 일하는 그룹의 구성원들은 스스로 매우 만족하며 안정감을 느끼는 경향이 있기 때문에 일자리를 옮기지 않는다.
      • 협업의 결과와 개인 프로그래머의 고립된 결과에 대한 질적 차이를 연구한 적이 없다.

자신의 코드를 읽어야 하는 모든 사람을 위해 프로그램을 명확하고 이해하기 쉽게 만들려고 항상 노력했던 것이다.

비자아적 프로그래밍 방식으로 개발된 프로그램이 그렇지 않은 프로그램보다 효율성에서 뒤쳐질 이유가 없음은 확실하다.

프로그램의 전체 효율성은 원작자가 고안한 구조에 주된 영향을 받겠지만, 다른 사람의 검토를 거치면 적어도 너무 뚜렷하게 비효율적인 부분은 미리 없어지기 때문이다.

또한 다른 사람이 작성한 프로그램을 읽는 사람에게도 좋은 영향을 미친다.

프로그램 읽기에 내포된 가치를 제대로 평가했다면, 비자아적 프로그래밍 방식으로 작성된 프로그램을 읽는 사람은 더 나은 프로그래머가 되지 않을 수 없다.

프로그래밍 환경의 조성과 유지

조성된 환경을 그냥 유지하는 것은 비교적 쉽지만, 기존 그룹을 새로운 환경으로 이끌려면 사회적 구조의 정착 또는 고착화 현상이라는 난관에 부딪힌다.

고착화는 어떤 상황이 자신을 유지하기에 더 적합한 환경을 만들어 내는 것을 말한다.

한 회사에서 프로그래밍 언어를 한 가지만 사용하는 것은 프로그래밍 환경에 관련된 사회적 고착화 현상의 전형적인 예다.

사회적 환경은 비자아적 프로그래밍을 장려하거나 또는 억제하는 방향으로 조성될 수 있다.

ex) 조언에 대해서 냉소적인 반응, 서로 협력하는 관계

우리가 취하는 행동에서 상당 부분은 환경적인 영향을 많이 받기 때문에 프로그래밍 그룹에 새로 합류한 사람은 그 그룹의 철학에 맞춰 사회화된다.

고위 관리자들이 비 자아적 프로그래밍 철학을 위협하는 경우도 종조 있다. (상업적 생각이 우선)

  • 그룹의 이전 사례
    • 그룹(팀)은 덩어리다.
    • 함께 일함으로써 얻는 성취감

요약

프로그래머의 작업 환경은 복잡다단하며 인간관계와 그 변화 그리고 오해를 불러일으킬 만한 상황들로 가득 차있다.

그 환경을 이해하라면, 공식적 구조와 비공식적 구조의 차이를 이해하고 물리적 환경에서 개인의 자아까지 환경에 영향을 미치는 다양한 요소들도 이해해야 한다.

그리고 프로그래밍 환경에는 외부로부터 발생한 변화에 저항하는 자기보존성이 있다.

특히, 그 변화가 공식적인 것과 비공식적인 것의 차이를 이해하지 못한 상태에서 이루어질 경우에는 더더욱 그렇다.

이런 자기보존성은 모든 차원의 사회에 존재하는 현상이고, 본질적으로 좋지도 나쁘지도 않다.

그저 프로그래밍의 현실일 뿐이다.

추가 (보태는 글)

과거와 다르게 메일을 사용(지금은 메신저)한다.

장점으로는 비가시성이 존재한다.

3장의 생각 MBTI로 개발자들을 테스트내용

논의사항

좋은 프로그램을 정의하기가 어렵다는 사실은 자치하고

  • 위 내용에서 스스로 생각하시는 열등한(Badcase)에 대한 논의는 저번에 다뤘는데 이번엔 책에서 말하는 ‘좋은 프로그램’을 정의하기 어려운 이유에 대해서 논의해보면 좋을 것 같습니다.

5장 프로그래 팀

개발하려는 시스템의 크기가 클수록 프로그래밍 경험 부족이 더 여실하게 드러나기 마련이다.

이상적으로는 프로그래머들이 사소한 문제라도 결코 혼자 작업하지 않는다고 보았지만, 작은 프로그램과 큰 프로그램은 사회적 측면에서 서로 차이가 있다.

어떤 한 명이 그룹 전체의 작업을 목표와 일반 체계부터 아주 작은 코드의 세부 사항까지 숙지할 수 있다면 프로그래밍 작업을 통합할 필요는 없다. (인간 문서)

프로그램을 서로 모두 이해하고 있는 상태에서 함께 개발하는 두 프로그래머의 상호 작용과 한 사람이 맡기엔 너무 커서 프로그램을 둘로 나눠 작업하는 두 프로그래머의 상호 작용은 전혀 다르다.

특히 요구사항의 충돌이 해소되는 방식이 다르다.

전자의 경우에는 한 사람의 사고 과정 즉, 가끔 다른 이의 도움을 받기도 하지만 늘 스스로가 통제하는 사고 과정을 통해 충돌이 해소된다.

반면 후자는 기술적인 요구사항이 충돌이 대인 관계의 갈등으로 번질 가능성이 있으며, 이 문제를 해결하기 위해서는 사회적인 장치를 갖추어야 한다.

팀을 어떻게 조직할 것인가

한 사람이 감당할 수 없는 업무 요구사항을 만족시키려면 프로그래밍 팀을 조직해야 한다.

그 필요성은 단순히 해야 할 작업의 요구 명세뿐만 아니라 그 일에 필요한 사람들의 능력과 할당될 시간과도 관련되어 있다.

그 2가지 요소 즉, 팀 구성원의 능력과 가용 시간에는 작업을 수행하는 데 요구되는 최소치가 있다.

예를 들어 어떤 프로그래밍 작업은 팀 크기가 아무리 크다 해도 초보자들만으로는 불가능하기 때문에, 경제에서 말하는 인력을 두 배로 늘려도 전혀 소용이 없을 것이다.

개념상, 목적한 시스템을 개발하는 데 필요한 최소의 전문 기술과 최소의 시간이 있다.

그러나 이 수치들은 정확하게 정의하기 어려울 뿐 아니라 프로그래밍에서 추정은 항상 불확실성이 개입되기 때문에, 관리자는 상식적으로 봤을 때 계획된 시간 내에 주어진 업무를 절대 수행할 수 없는 팀을 구성하곤 한다.

십중팔구, 이런 팀은 마감 시한이 닥쳐 현실을 직시해야만 하는 상황이 되어서야 일정 연기를 요청한다.

현실을 좀 더 일찍 깨달았더라면, 일정이 길어짐을 고려해 그에 맞춰 작업을 다르게 계획할 수 있었을 테고, 결국 일을 더 빨리 마칠 수 있었을 텐데 말이다.

너무나 흔히 목격되는 이런 상황으로부터 능력과 일정 간의 상호 보완 관계를 알 수 있다.

최단 일정은 오로지 최고의 팀을 프로젝트에 투입할 때에만 달성 가능하며, 팀의 인원을 최소로 투입하려면 프로젝트 일정이 늦어짐을 각오해야 한다.

다시 말해서 프로그래밍 기술이 다소 부족하다 해도 일정을 연장해 줄 여유가 있고 능력이 최저 수준 이하만 아니라면, 어떤 프로그램이든 만들어 낼 수 있다.

또 일정과 작업 진척 간의 중요한 관계도 알 수 있다. (파킨스의 법칙)

파킨스의 법칙이란 주어진 시간을 다 채울 때까지 작업을 지연시킨다.

파킨스의 법칙도 경계해야 할 대상이긴 하지만, 너무 빠듯한 일정을 핑계로 위험한 지름길을 택하는 것도 피해야 한다.

지름길을 통해도 시스템을 제 시간 내에 성공적으로 가동시킬 수 있을지도 모른다.

반면에, 일정에 착오가 생길 가능성에 대비하려 한다면 팀에 정원 외 인력을 충원해야 한다.

그러나 작업을 더 많은 사람이 분담할수록 전체 작업의 통합이 더 어려워진다는 점을 고려해야 한다.

어림잡아, 프로그래머 3명으로 구성된 팀은 작업을 통합하는 데 소요되는 시간 때문에 동등한 능력을 지닌 프로그래머 한 명이 할 일의 2배 밖에 하지 못한다.

더 나아가, 각각 프로그래머 3명으로 이뤄진 팀 3개는 마찬가지 이유로 팀 하나가 할 일의 2배, 또는 프로그래머 한 명이 할 일의 4배밖에 할 수 없다.

따라서 프로그래머 한 명이 8달 안에 마칠 수 있는 프로젝트에 3명을 투입하면 4달만에, 9명을 투입하면 2달만에 끝낼 수 있다.

더 뛰어난 프로그래머도 있지만, PM의 역할도 중요하다고 생각된다.

최소의 비용으로 최고의 프로그래밍을 원한다면, 가능한 한 최고의 프로그래머를 구하고 그들에게 최소한의 인원으로도 문제가 없을 만큼 충분한 시간을 주어야 한다.

이것이 프로그래밍 팀의 크기와 구성에 대해 언제나 통용되는 기본 원칙이다.

일을 더 빨리 해야 하거나 덜 숙련된 사람들과 일해야 한다면 비용과 불확실성이 더 증가하게 된다.

최악의 방식은 초보자들만 고용한 뒤 스트레스만 주고 감독은 하지 않으면서 일을 시키는 것이다.

경험이 없는 프로그래머는 반드시 훈련이 필요하고, 미숙하더라도 팀에 포함시켜 업무 구조 자체를 생산과 훈련으로 변경해야 한다.

프로그래밍 팀을 조직하는 방식을 결정하는 데는 목표 시스템의 구조와 팀의 구성이라는 두 가지 요소가 강력한 영향을 미친다.

시스템의 구조에 접근하는 방식은 다양할 수 있는 데 반해 그 일에 투입할 수 있는 프로그래머들은 한정된 경우가 많기 때문에, 팀 구성원 개개인이 지닌 강점과 약점을 잘 살릴 수 있는 조직 구조로 선택하는 경우가 많다.

콘웨이의 법칙

이상적인 방향은 프로그램 구조를 먼저 계획하고 그 작업을 가장 잘 수행할 수 있는 사람들을 모으는 것이 옳은 순서다.

그러나 재능 있는 프로그래머가 부족하기 때문에 현실적으로 그렇게 하기 힘들다.

가장 중요한 요인 중 하나가 바로 누가 누구의 작업을 비판하는가이다.

따라서 비자아적 프로그래밍을 실천한다면 팀원이 모두 언젠가는 모든 동료의 업무를 자세히 검토할 수 있는 기회를 갖게 되므로 조직의 계층성이 강해지는 것을 막을 수 있다.

프로그래밍에서 팀원의 지위는 대체로 다른 사람들이 그의 능력을 어떻게 평가하는가에 큰 영향을 받는다.

서로 작업을 검토하면서 팀원에 대한 평가가 전체적으로 공유되면, 실력자가 윗자리로 올라가는 속도가 빨라진다.

다른 한편으로, 어떤 업무를 맡느냐에 따라 지위를 얻을 수도 혹은 잃을 수도 있다.

목표의 수립과 합의

어떤 팀원이 사소한 업무를 할당 받아서 감정이 상한다면 팀 전체에 매우 나쁜 영향을 줄 수 있다.

반면에 비자아적 프로그래밍을 실천하면, 프로그래머 각자가 전체 시스템에 대해 자기 나름의 몫을 하고 있다고 느끼게 되므로 그런 감정이 한층 완화된다.

그렇다 해도, 팀이 프로젝트의 구조와 업무 분배에 대한 완전한 합의를 이끌어내기 전에 너무 성급하게 일을 시작한다면 어떤 형태로든 문제가 발생할 것이다.

사회 심리학자들은 맥락은 좀 다르지만, 한 명 이상의 구성원이 그룹의 목표를 공유하지 못하면 그룹 전체의 업무 효율에 악영향을 미친다는 사실을 증명했다.

목표를 공유하지 못하면 단지 그 구성원 한 사람의 문제로 끝나지 않고, 다른 구성원들이 그룹 내의 분열이나 일부 동료의 무관심한 태도를 피부로 느낄 수밖에 없기 때문에 업무 능률이 떨어지게 된다는 것이다.

프로그래밍 작업을 편견 없이 평가하는 데 꼭 필요한 건전한 논쟁을 억누르는 그릇된 합의와 팀의 생산적 활동을 원활하게 하는 팀의 목표에 관한 합의는 전혀 다르다는 것이다.

그룹의 목표에 대한 진정한 합의를 얻기 위해서는 그 그룹이 목표를 직접 설정하도록 하는 것이 가장 좋은 방법이다.

  • 목표를 한층 분명하게 이해할 수 있다.
  • 목표 설정에 참여한 각 구성원은 그룹의 목표를 실현할 것을 공개적으로 약속한 셈이 되고, 그렇게 공개적으로 약속한 사람은 인지부조화 현상으로 인해 목표를 더 잘 인정하고 받아들이게 된다.

그러나 무엇보다도 참여 자체가 다른 요소들과는 완전히 독립적으로, 어떤 개인이 진정으로 팀의 실제 목표를 인정하여 그만큼의 생산성 향상을 보일지 여부를 결정하는 중요한 요인인 것으로 보인다.

팀원들이 협력을 통해 세부사항을 결정해야 하지만, 고위 관리자가 정의하려 한다면 팀원들은 단순 코더로 느껴질 수 밖에 없다.

프로그래머는 단순히 무엇을만이 아니라 왜인지도 알고 싶어한다.

프로그래밍 팀이 특정 시스템을 제작하는 일이 아니고 다른 프로그래밍 그룹에게 어떤 서비스 또는 지원 함수를 제공하는 일을 하는 경우, 분명하지 않은 목표의 문제는 한층 더 심각해진다.

그러나 주 업무가 지원인 그룹은 끊임없이 자신이 맡은 바를 되새기지 않으면 더 구체적이지만 덜 생산적인 방향으로 흘러버릴 위험이 크다.

사소한 논쟁이라도 쉽게 무시해서는 안된다.

팀 리더십과 팀 리더

프로그래머의 리더는 강압적이거나 원칙적이면 안된다.

사회학자들이 업무 집단의 만족도에 영향을 끼치는 요인들을 다음과 같이 크게 4가지로 분류했다.

  • 물질적인 보상과 기회
  • 일 자체가 불러일으키는 의욕과 흥미
  • 조직 전반의 일반적인 조건들 (근로자 복지, 근무 환경, 비슷한 조직들 사이의 상대적인 위치)
  • 관리자의 리더의 능력

과거와 다르게 이직율이 높은 지금은 성장을 좀 더 높게볼 것 같다.

프로그래머는 창조적인 사고와 전문 느력을 중요시하는 사람으로, 자신의 분야인 프로그래밍에 뛰어나다고 판단되는 사람을 신뢰하고 높이 평가하는 경향이 있다.

리더가 할 수 있는 최악의 행동은 다른 팀원들과 프로그래밍 지식을 겨루려고 하는 것이다.

민주적인 집단에서 리더십은 한 사람에게 국한되지 않고 당시의 요구에 들어맞는 능력이나 생각을 소유한 구성원에게 계속 옮겨 다닌다.

그러나 사람이 모두 평등하게 태어날지 몰라도 똑같지는 않는다.

따라서 민주적인 팀의 리더십도 절대 균등하고 나눠지지 않으며, 어떤 팀원은 상대적으로 많은 리더십을 행사한다.

외부의 영향을 받지 않고 내부의 현실 상황에 맞춰 리더십이 정해지는 것이다. (계속 바뀌는 리더)

하지만 적절한 리더를 찾을 수 있는가라는 측면에서 보면 어떤 프로그래밍 팀도 완벽하게 민주적일 수는 없다.

우선, 팀 내에 적합한 인물이 없을 수도 있다.

두번째로, 인성의 문제가 당면한 상황에 적절한 리더를 선택하는 데에 걸림돌이 될 수도 있다.

마지막으로, 외부로부터 리더가 임명되어 들어오면 반드시 그 집단은 민주주의에서 멀어지게 된다.

팀 리더가 반드시 명심해야 할 사항은 다음과 같다.

  • 경영자가 약속 이행을 아무리 강하게 요구한다 해도, 진정으로 원하는 것은 결과물 자체다.
  • 팀 전체가 참여하여 설정한 목표를 추구한다면 결과물을 훨씬 더 쉽게 얻을 수 있다.

외부에서 온 리더라도 위 사항을 잘 지킨다면 지배력을 지도력으로 대체할 수 있다.

리더로서 자신감이 있다면, 언제든 물러날 준비가 되어 있는 리더만이 진정한 성공의 열쇠를 쥐고 있다.

팀의 위기

팀의 생명 주기는 팀원 고용을 시작으로, 목표를 설정하고 업무에 맞춰 내부를 조직하는 과정을 거쳐, 결국 업무가 완료되거나 새로운 목표를 받아들일 때 해산됨으로써 끝을 맺는다.

편의상 팀 활동은 두 가지 범주 즉, 팀 목표를 성취하려고 수행하는 일과 위기가 닥쳤을 때 팀을 효율적으로 유지하고 관리하고자 행하는 일로 나누어 생각할 수 있다.

사회 심리학에서는 이런 활동들을 각각 업무 지향적 그리고 관리 지향적이라고 부른다.

민주적으로 조직된 팀은 승진, 사직, 병, 죽음, 임신, 출가 등 어떤 이유로든 구성원을 잃을 때 받는 충격을 잘 견디는 경향이 있다.

팀원끼리 공유와 의사소통이 활발하기 때문에 업무에 대한 이해도가 높을 수 밖에 없다.

하지만 새로운 구성원에 대해서는 받아들이기 힘든 것으로 알려져 있다.

이미 팀원끼리 강한 결합도를 가지고 있었기 때문에 (인간 문서와 같이) 이런 관계를 다시 맺는 것이 어려울 것이다.

반대로 권위적인 팀의 구성원들은 새로 온 사람에게 아주 친절하고 호의적인 반면, 민주적으로 조직된 팀은 다소 냉정하고 비우호적인 모습으로 비춰지곤 한다.

모든 일을 오로지 단 한 사람의 리더가 조직하고 관리할 정도로 권위적인 성향이 강한 팀에서는, 구성원 중 하나가 이탈하여 생긴 구멍이 그대로 방치된다.

오직 리더만이 남은 구성원들에게 일을 다시 분배하는 데 필요한 정보를 쥐고 있다.

민주적인 집단에서는 철저하게 무능력한 구성원보다 유능하지만 다른 사람들과 잘 어울리지 못하는 구성원이 훨씬 더 심각한 문제가 될 수 있다.

권위적인 집단이라면 구조적으로 무능력한 구성원이 업무에 관해 다른 사람들과 접촉할 기회가 많지 않을 것이다.

따라서 리더와 원만하게 지내는 한 특별히 문제가 되지 않는다.

수동적인 직원일수록 강력한 중앙 집권적 리더 아래에서 일하기를 선호하고, 능동적인 직원일수록 민주적인 리더에서 일하길 선호하는 것 같다.

팀의 위기가 반드시 특정 개인과 연관되는 것이 아닌 발전 단계나 외부 환경의 변화에 의해서도 발생할 수 있다.

일반적으로 팀의 조직 형성은 냉동실에서 얼음을 얼릴 때와 같이 아래쪽에서 위쪽으로 그리고 위쪽에서 아래쪽으로 동시에 진행된다.

한 팀에 강력한 리더의 소질을 지닌 사람이 두 명 있다면, 위쪽으로부터 팀이 형성되는 과정이 오랫동안 진행되지 못하고 질질 끄는 경우가 있다. (비생산적이지만, 분리하면 해결)

어떤 사람이 리더의 자질이 강한 사람인지는 팀에 주어진 작업 요구에 따라 다르다.

앞서 말한 기본적인 룰을 지킨 상태에서 리더는 계속 변경될 수 있어야 함.

집단 행동에 관한 보편적인 사회심리학 연구 결과 중에서 특히 다음 두가지는 위기로 점철된 프로그래밍 팀을 정확히 설명한다.

  • 위기 시에 비교적 강력한 리더십을 행사하려는 시도는 구성원들이 비교적 거부감없이 받아들인다.
  • 그러나 그와 동시에 그 자칭 리더가 집단의 문제에 대하 효과적인 해결책을 빨리 내놓지 못하면 나머지 사람들은 느긋하게 지켜보지 못하고 금세 조바심을 낸다.

이러한 이유 때문에 민주적인, 기술주의적인 조직이 왜 프로그래밍 팀에 그토록 딱 맞는 조직 형태인지 알 수 있을 것이다.

따라서 프로그래머를 뽑을 때 끊임없이 변하는 구조에 적합한 사람 즉, 너무 지배적이지도 너무 수동적이지도 않은 사람을 찾아야 한다.

또, 프로그래머를 훈련시킬 때에는 유능한 리더를 어떻게 따라야 하는지 그리고 스스로 집단 내에서 리더로 가장 적입자일 때 어떻게 그 기회를 잡아야 하는지를 가르쳐야 한다.

외부세력은 이러한 민주적인 활동에 간섭하지 않아야 한다.

현명한 관리자라면 팀이 발족되어 활동을 시작하고 난 후에는 팀의 내부 구조와 그 변화에 관해 일종의 무간섭 정책을 펼칠 것이다.

요약

대부분의 상황에서 프로그래밍의 가장 중요한 작업 단위는 팀이지 개인이 아니다.

보태는 글

한 사람이 감당할 수 없는 업무 요구사항을 만족시키려면 프로그래밍 팀을 조직해야 한다.

현대에는 업무 요구사항이란 용어를 좀 더 넓게 해석하여 팀과 팀원의 능력 개발을 포함하는 개념이라고 생각한다.

논의사항

사회학자들이 업무 집단의 만족도에 영향을 끼치는 요인들을 다음과 같이 크게 4가지로 분류했다.

  • 물질적인 보상과 기회
  • 일 자체가 불러일으키는 의욕과 흥미
  • 조직 전반의 일반적인 조건들 (근로자 복지, 근무 환경, 비슷한 조직들 사이의 상대적인 위치)
  • 관리자의 리더의 능력

과거와 다르게 이직률이 높아진 지금 여러 요인이 생기도, 우선순위가 달라지도 한 것 같습니다.

우선순위와 추가할 만한 요인에 대해서 논의해보고 싶습니다.

6장 프로그래밍 프로젝트

어떤 프로그래밍 목표를 이루기 위해 두 팀이 함께 일해야 하는 상황에서는 두 프로그래머가 함께 일하게 될 때와 마찬가지로 중간에서 조율 기능이 타나난다.

또 개인이 모여 팀을 이룰 때와 마찬가지로 새로운 형태의 사회관계도 형성된다.

  • 두명의 프로그래머는 개인으로 상호작용 하기도 하지만, 다른 팀에 속한 구성원으로서도 상호 작용한다.
    • 다른 팀원의 평가를 받음

변화를 통한 안정

대규모 조직이 지닌 특성 중 가장 흥미로운 것은 구성원 개개인의 수명보다 더 오래 존속한다는 점이다.

프로그래밍 팀도 최초 구성원들은 다 떠났지만 팀은 유지되는 경우를 볼 수 있다.

이러한 특성은 조직의 큰 강점이며, 상호 작용을 통해 팀의 목표와 성취가 새로운 구성원에게 전달되고 또 기존 구성원이 떠난 후에도 그대로 유지되기 때문이다.

가끔 프로젝트의 핵심인력에 대한 잘못된 태도로 비참한 결과를 맞기도 한다.

  • 마크의 생산 공정 사례
    • 핵심 인력의 합당한 요구를 거절
  • 헨리의 제어 프로그램 사례
    • 꾸준한 변화를 통한 안정

프로젝트가 진행되면서, 사람들은 현재 하고 있는 제한된 업무에 비해 더 흥미로워 보이는 새로운 것들을 배우기 마련이다.

또는 자신의 능력에 비해 너무 쉽게 느껴지는 업무가 지겨울 수도 있다.

모든 프로그래머가 어려운 업무에 도전하는 것을 즐기지는 않지만, 대부분은 자신의 지식을 적용해 볼 기회가 없다면 불만족스러워 한다.

따라서 프로젝트가 일종의 프로그래머 생산 공장으로 기능하도록 만들어야 한다.

또한 프로젝트는 카드로 지은 집이 아니다.

핵심 인력이 한명 없다고 붕괴되지 않는다. (그러지 말아야 한다.)

절대 없어서는 안 될 프로그래머가 있다면, 한시라도 빨리 그를 프로젝트에서 제거하라.

성과의 측정

프로젝트의 규모가 클수록 성과를 측정하기가 더 어렵다.

규모가 너무 크면 한 사람이 전체를 판단하기 불가능하다.

또, 개별 프로그램의 친척도에 대한 판단은 주관적인 문제이므로 다른 요인이 없는 상태에서도 각양각색일 것이다.

그러나 어떤 프로그램 하나에 대한 여러 사람의 의견을 들어 볼 기회는 없다.

대신, 프로젝트라는 큰 그림 내에서 여러 프로젝트에 대한 여러 사람의 의견을 비교하고 종합해야 한다.

그렇게 의견을 종합하는 과정에는 심리적인 문제가 발생할 다양한 가능성이 존재한다.

  • 군사 프로젝트의 예
    • 프로그래밍 팀의 보고서가 친척도가 아닌 예상으로 채워졌지만 그 괴리를 걱정하는 사람은 없었음
    • 별로 가능해 보이지 않아도 사람들이 믿으려 하는 경우가 있다는 사실
    • 보고서를 검토하는 사람의 지위 및 보고서 작성에 실제로 공헌하는 정도와 검토에 소비하는 시간 사이의 흥미로운 관계다.

학습 효과를 극대화하려면 학습 주체가 자신에 대한 평가를 피드백으로 받아야 한다는 심리학적 원칙은 잘 알려져 있다.

사례의 보고 체계는 일련의 필터들로 생각할 수 있는데, 각 필터는 시간 진여과 정보 손실을 어느 정도 수반한다.

이런 의미에서 정보는 놀라운 소식일 경우에만 보고서를 통해 전달된다.

심리학 실험에서 피실험자들에게 선형적인 잣대로 뭔가를 평가하게 하면, 극단적인 값을 택하는 사람은 거의 없다.

실제로 5단계의 등급 구별이 필요하다면 7~9단위의 값이 사용되고 양쪽 극단의 값은 옆의 값과 함께 뭉뚱그려진다.

이련 효과가 각 단계를 지나면서 보고서가 여과되는 현상과 관련이 있다.

이전의 검토자가 손대지 않은 극단적인 값을 각 단계의 검토자가 없앤 것이다.

따라서 보고서의 수치들은 위로 올라가면서 점점 더 중간값을 향하게 된다.

그럼으로써 실질적으로 전달되어야 할 정보를 여과한다.

이런 문제를 막기 위해서는 먼저 극단적인 값을 평범한 값으로 조작하는 경향이 지닌 심리적 원인을 찾아야 한다.

  • 인지부조화
    • 관리자가 작업이 순조롭게 진행되도록 하는 게 좋은 관리자라고 믿는다면, 진척도가 요동치는 상황은 인지부조화 상태를 야기한다.
    • 그리고 그렇게 진척도의 부침이 심한 것은 큰 그림을 보기에는 사안에 너무 가까이 있는 실무자가 잘못 판단한 결과일 뿐이라고 믿어버릴 것이다.
  • 상부의 압력
    • 상부의 압력은 일을 추진하는 동력이 되기도 하지만 보고 체계를 파괴하는 힘이 되기도 한다.
    • 관리자가 배워야 할 것은 사람들이 일을 하는 방식을 바꾸거나 작업 능률을 올릴 수 있도록 자극을 주는 방법이다.
    • 현재 프로젝트의 진행상황을 감춰야만 하는 분위기가 조성되서는 안된다.
  • 동료의 역할

침묵의 나선이론

내 편이 한 명이라도 존재하면 사물을 있는 그대로 볼 용기가 생기는 것이다. (동조)

  • 데블스 에드버킷은 실제로 영어권에서 사용하는 표현인데, ‘논리적 오류를 편드는 사람’

프로젝트의 구조

프로그래밍 프로젝트에서 진척도 평가에 관련된 심리적 함정을 극복하려면, 실무와 그에 대한 평가를 어떤 식으로든 분리하는 것이 필수다.

그런데 계층 조직의 가장 심각한 약점이 바로 이 분리가 불가능하다는 것이다.

실무에 대한 통제 경로가 그대로 진행 보고 경로의 역순이기 때문이다.

앞서 다룬 보고 경로를 따라 전달되는 정보에 왜곡이 생기기 마련이다.

이런 왜곡을 방지하고자 단순히 계층적인 형태에서 탈피한 구조가 나타나기 시작한다.

QA팀을 두거나 인력을 버퍼로 설정하여 필요할 때 조직한다.

조직을 개편하려 하면 생각보다 많은 문제가 발생할 수도 있다.

다른 그룹으로 옮기거나 어떤 사람과 함께 일하는 것 또는 특정 업무를 맡는 것을 거부하는 사람들이 생긴다.

어떤 사람과 계속 함께 일을 하거나 현재 업무를 계속 해야겠다고 우기는 경우도 있다.

본질적으로 이런 문제들은 모두 차별에서 비롯된다.

이는 한 개인이 정해진 팀에 속해 일할 때에 발생하는 문제와 유사하다.

팀 구성원 각자는 팀 목표를 일정 부분 자기 것으로 받아들인다.

그러나 특화된 팀을 경우에는 팀 목표가 프로젝트 전체의 목표 또는 다른 팀의 목표와 일치하지 않을 수도 있다.

예를 들어, 특정 업무가 다른 일보다 시시한 것으로 치부될 수 있다.

ex) 문서화 그룹에 대한 프로그래밍팀의 무시

비자아적 프로그래밍에 관한 경험으로 절친한 친구라고 해서 가장 엄격한 비판자가 되지 못할 이유는 없다.

프로젝트 내의 자연스런 반목은 경영진과 프로그래머라는 수직 계층 사이에서도 발생한다.

이 반목은 목표의 수립 때부터 나타나는데, 프로젝트의 목표가 각 팀의 목표의 단순함은 아니기 때문이다.

보통, 목표는 하향적으로 수립되며 주요 사항은 팀 조직이 갖춰지기 전에 이미 결정된다.

그런 상황에서는 팀 목표의 수립도 민주적으로 이뤄지길 바랄 수 없다.

결국, 프로그래머들이 프로젝트는 물론이고 자신의 팀에도 충성심을 갖기 어려워진다.

대규모 프로젝트에서 공통적으로 발생하는 사회 문제

대규모 프로젝트에서 발생하는 사회적 문제에서 대부분의 원인은 프로젝트 리더십과 실무자 사이의 먼 거리에 있다.

프로그래밍 팀 내에는 딱 두가지 역할만 있으면 된다. (프로그래머와 그 리더)

그러나 프로젝트 전체를 놓고 보면 리더의 리더 즉, n차 관리자가 있다.

n차 관리자는 하위 관리자들을 통해 간접적으로만 볼 뿐이다.

관리자가 스스로 이해하지 못하는 일을 감독할 때에는 언제나 실무자를 평가하는 기준이 일 자체가 아니라 일하는 모습이 된다.

프로그래밍 분야, 관리자의 지위의 상징에 관한 이야기는 너무 과거의 이야기라 생략

논의사항

비자아적 프로그래밍에 관한 경험으로 절친한 친구라고 해서 가장 엄격한 비판자가 되지 못할 이유는 없다.

  • 현업에서는 친한 직장동료와 솔직한 관계를 어떻게 유지 하시나요?

3부 개인 행위로 보는 프로그래밍

나는 이름을 붙일 가치가 있는 자유는
개인에게 잠재된 물질적, 지적, 정신적 능력을 최대한 개발할 자유뿐
이라고 생각한다. 그 자유에 다른 제한은 없다.
오직 우리의 본성이 정한 법칙에 따를 뿐이다.
다시 말하면, 사실 제한이 전혀 없다고 할 수 있다.
미하일 바쿠닌

앞 장의 내용에서 프로그래밍 성과가 프로그래머마다 차이가 나는 원인으로 대부분 사회적인 요인에 기인한 것으로 설명했다. 그러나 대부분을 사회적 요인으로 돌린다 하더라도 여전히 남는 부분이 있다. 두 프로그래밍 구조가 아무리 비슷하더라도 최종 결과물은 다를 것이다. 이 차이를 개인에 관련된 여러 요인으로 설명한다.

실험을 수행하는 심리학자는 제일 먼저 모든 실험대상에게 같은 임무를 주었는지를 자문해야 한다. 아무리 잘 통제된 실험일지라도 실험대상에게 주어진 입무에는 많은 차이가 있기 마련이다. 또한 의미있는 결론을 얻기 위해선 임무의 차이를 먼저 찾아야 한다. 프로그래밍 입무는 여러 가지 측면에서 서로 매우 다르다. 따라서 제일 먼저 살펴볼 부분은 프로그래밍 임무 간의 차이다.

실험의 목적에 따라 달라지는데, 대상간의 개인차를 측정함이 목표라면 모든 실험 환경을 동일하게 만들어 환경이 유발하는 차이를 막아야 한다. (앞서 환경의 차이가 주는 내용을 학습했다.) 온도, 파티션등 실험 대상의 측정 목적에 영향을 줄 수 있는 모든 환경은 통일해야 한다.

반대로 측정하고자 하는 것이 온도나 환경에 의한 것이라면 그에 대한 차이를 제외한 나머지 요소를 똑같이 조성해야 한다.(업무, 시간 등등)

3부에서는 심리학자가 말하는 이런 개인차를 몇 가지로 나누어 다룬다. 두 사람에게 동일한 환경과 임무를 준다면 각 개인이 보이는 행동의 차이는 이요인들에 의해 나타난다고 간주하는 것이다. 따라서 우리가 관심을 가져아 할 개인차는 크게 개성, 지능, 훈련 또는 경험으로 분류할 수 있다.

물론 모든 것이 환경적인 요인에 의해 결정되는 것은 아니지만, 환경적인 요소에 따라 달라지는 내용이 많기 때문에, 이를 조심해야 한다. (총균쇠)

7장 프로그래밍 작업의 다양성

프로그래밍이란 단어는 무수히 많은 행위를 포괄한다. 단순하게 고등학생이 코드를 적는것 과 작업 프로그래머가 특수 목적의 온라인 컴퓨터를 위해 될수록 용량이 적은 프로그램을 개발하려 노력하는 것도 역시 프로그래밍이다.

프로그래밍의 프로와 아마추어

위에서 다룬 고등학생과 프로 프로그래머의 프로그래머 스펙트럼의 양 극단을 대표한다고 하자. 이 양 극단은 다를 수도 혹은 같을 수도 있다. 그러나 프로가 아마추어보다 프로그래밍에 대해 더 많이 공부하고 실습했음은 분명하다. (차이가 없는 경우도 존재하지만 대부분의 경우 차이가 존재한다.)

가장 큰 차이는 누가 그 프로그램을 사용할 것이냐에 있을 것이다. 아마추어는 자신만이 사용할 요량으로 프로그램을 만든다. 그러나 프로는 다른 누군가가 사용할 프로그램을 만든다. 물론, 프로도 자신만 쓸 프로그램을 만들기도 한다.

이 차이는 실제로 다른 사람이 그 프로그램을 사용할 때 나타나며, 다른 사람이 실제로 사용한다는 점이 프로그래머 작업에 여러가지 영향을 미친다.

아마추어는 문제를 단순하게 만들어 버리거나 정의하는 사람이 본인일 수 밖에 없다. 프로는 자리에서 일어나 프로그램 수정을 허락하거나 요구 명세를 명확히 규정해 줄 다른 사람을 찾아가야 하기 때문이다.

심지어 프로그램 개발을 마친 후의 일은 더 간단하다. 아마추어는 그냥 잊어버리면 끝인 반면에, 프로는 프로그램을 잘 포장하여 냉혹한 세상으로 내보내야 한다. 그 후에는 자신에게 돌아오는 신랄한 비판에 따라 프로그램을 여러모로 수정해야 한다.

  • 과연 관리자는 프로그래밍에 대해서 알아야 하는가?
    • 과거에 비해선 현대에선 과정에 대한 이해는 필요하다고 생각한다.

아마추어는 주어진 문제에 대해 배운다. 그리고 그가 배운 것은 뽐낼 만한 장식이 될 수도 있고 발전의 장애가 될 수도 있다. 반면에, 프로는 자신의 직업에 대해 배운다. 지금 다루는 문제는 그가 발전하는 과정의 한 단계일 뿐이다.

또한, 프로는 어떤 문제도 아마추어만큼 심각하게 생각하지 않는다. 그에게는 항상 버그가 있었고 앞으로도 그럴 것이기 때문이다. 이런 태도의 차이는 프로와 아마추어 간의 끊임없는 마찰로 이어진다.

프로그래머가 하려는 것이 무엇인가?

아마추어와 프로의 관계에는 불균형이 있다. 아마추어는 프로가 직면하는 복잡성을 이해할 수 없기 때문이다. 그런데 프로도 아마추어의 작품을 전문성이 떨어진다고 비웃는 우를 자주 범한다. (매우 위험) 이는 아마추어가 자신과 프로의 차이를 과소평가하는 것보다 더한 잘못이다.

프로는 아마추어보다 훨씬 잘 알아야 한다. 아마추어는 우아한 에러 처리 루틴을 만들지 못할 수도 있다. 어떻게 만드는지 혹은 에러 처리 루틴이 무엇인지조차 모를 수 있다. 그러나 그에게 필요하지도 않은데 꼭 알아야 하는가? 아마추어가 그런 걸 모르는 것보다는, 프로가 개인적인 용도로 만든 작은 프로그램을 마치 수천 명의 사람이 5 내지 10년 동안 사용할 운영체제인 듯 대하려 하는 쪽이 더 나쁘다.

개인적인 경험으로도 당장 필요하지 않은 기술, 내용을 학습한 것에 대해서는 정말 도움이 되지 않은 것 같다.

프로그램은 사람이 만드는 다른 모든 물건처럼 명확한 수명과 활용 범위를 염두에 두고 설계된다. 수백 년 동안 유지될 수 있을 만큼 논리적인 방법으로 만든 장인의 작품처럼, 프로그램에는 과도하게 설계된 부분도 미진하게 설계된 부분도 있어서는 안 된다.

실제로 환경이 성과에 미치는 영향을 알아보기 위해 실험을 통해 알아본다.

효율성을 추구하는 그룹은 더 많은 컴퓨터 시간과 개인 시간을 사용한 원인은 예기치 않은 어려움에 부딪혔을 때 대처하는 방식의 차이가 큰 요인임을 발견했다. 빨리 완성하려는 그룹은 현재의 수단이 동작하지 않으면 버리고 다른 수단을 찾는다. 그러나 효율성을 추구하는 그룹은 어려움이 생겨도 접근 방법을 바꾸려고 하지 않는다.

따라서 양 그룹의 두 프로그래머가 처음에는 같은 접근 방법을 머릿속에 그리고 있었다 할지라도, 빨리 완성하는 것이 목표인 프로그래머는 전혀 다른 방법으로 끝을 맺는다.

실제 어려움의 원인이 결과와 다소 관계가 없다는 점도 중요하다. 예를 들어 컴파일러의 어떤 버그로 인해 여러 접근법 중 한 가지를 못 쓰는 상황이라고 하자. 그런 상황에서 빨리 완성하는 것이 목표인 그룹은 문제가 컴파일러 버그로 판명나기도 전에 이미 그 접근법을 포기한다. 반면에 효율성을 추구하는 그룹은 그 문제를 끝까지 파헤쳐 어쩔 수 없음을 알게 될 때까지 포기하지 않는다.

심리학 관점에서는 동일한 객관적 사건이라 할지라도 프로젝트의 목표에 따라 사건이 프로젝트에 미치는 영향은 다르다. 따라서 프로그래머의 성과를 측정하거나 언어, 운영체제의 성능을 비교하려면 주어진 문제가 정확히 동일함이 보장되어야 한다.

물론, 실생활에서 두 그룹이 정확히 동일한 문제를 동시에 다루고 있는 경우는 없다고 할 수 있다. 따라서 한 그룹 내의 관리자와 프로그래머들이 전혀 다른 목표를 추구하고 있더라도 그 사실을 인지할 수 없을지도 모른다. 결론적으로, 끊임없이 의사소통하여 목표를 공유하지 않는다면 일정이 지연된다거나 프로그램의 속도가 느리거나 메모리를 많이 사용하는 등의 문제가 생긴다 해도 놀라지 말아야 한다.

그러나 인생은 그렇게 간단하지 않다. 목표를 아무리 잘 공유해도 어느 정도의 위험은 피할 수 없다. 목표가 추정에 영향을 주기 때문이다. 앞의 실험에서 우리는 목표가 성과에 미치는 영향을 발견한 다시 확인한 결과로 알 수 있다.

최대한 빨리 완성하기를 요구 받은 프로그래머들이 상대적으로 훨씬 보수적인 추정치를 제시했다. 그리고 자신의 추정보다 더 나은 성과를 보였고, 효율적인 프로그램을 요구 받은 쪽과 비교해서도 더 나았다.(낙관적인 것을 제외해도)

신기하게 빠른 완성을 요구 받은 팀은 시간 추정을 거부하는 반응을 보였다.

여기서 목표를 명확하게 수립하면 생기는 두 가지 영향을 잘 알아봐야 하는데, 첫 째는 프로그래머는 다른 목표를 희생해서라도 그 명확한 목표를 달성하려 한다. 두번 째는 그 목표를 얼마나 잘 충족시킬지를 훨씬 더 보수적으로 추정한다.(또는 정확하게) 강조되지 않은 목표에 대해 프로그래머가 제시한 추정치는 믿을 게 못 된다.

이러한 실험의 결과가 일반적임을 증명한다면, 파킨슨의 법칙이 주는 의혹을 해소할 수 있고 동시에 수많은 관리자들을 악몽에서 구원할 수 있을 것이다. 파킨슨이 “일은 주어진 시간을 다 채울 때까지 늘어난다”고 말한 덕분에 우리는 목표 일정의 존재가 업무 능률에 영향을 준다는 걸 알게 됐다.

그러나 이제 우리는 목표 일정이 주어진 시간 자체에 영향을 준다는 것을 확인했다. 일이 주어진 시간을 다 채울 때까지 늘어날 수 있는 이유는 일정에 대한 다른 목표들의 상대적 중요성이 명확하지 않기 때문이다. 이런 식으로 사유해 나가면 “프로그래밍 프로젝트는 제때에 끝날 수 없다”는 통념을 낳은 오해들을 불식시킬 수 있을 것이다.

프로그래밍 작업의 단계

이번에는 또 다른 오해, “프로그래밍은 단일한 재능이 요구되는 단일한 작업이다”라는 통념에 대해서 알아보자.

적어도 프로는, 요구 명세 수집에서부터 최종 프로그램 납품에 이르는 과정 동안에 다양한 재능이 필요한 다양한 작업을 해야 한다.

적절하게 조직된 프로젝트에서는 프로그램 개발의 전 과정에 필요한 모든 재능을 모든 프로그래머에게 요구하지 않는다. 개인의 능력에 맞춰 업무를 할당하기 때문이다. 실제로 프로그래밍 작업의 한 단계에 적합한 어떤 재능이 다른 단계에서는 결점이 되기도 한다.

능력 있는 프로그래머가 관리자로는 실패할 수도 있는 것처럼, 훌륭한 설계자도 디버깅에는 서투를 수 있다. 반면에 디버깅에 큰 도움이 되는 사람이 설계 작업 동안에는 필요 없거나, 심지어 방해가 되는 어떤 재능으로 인해 프로젝트에서 제외될 수도 있다.

앞서 말한 때에 따라 팀장이 바껴야 하는 이유

적재잭소에 필요한 재능을 투입하려면, 프로그래밍 작업을 단순히 프로그래밍이란 한마디로 싸잡을 것이 아니라 더 정밀하게 세분화해야 한다.

일반적으로 프로그래밍은 문제 정의와 분석, 흐름도 작성, 코딩, 테스트, 문서화로 이어지는 일련의 과정으로 묘사된다. 이런 개략적인 관점에도 일말의 진실이 있기는 하지만, 몇 가지 점에서 진실을 왜곡한다.

우선, 작업의 순서가 그렇게 고정되어 있지는 않다. 예를 들어, 문서화가 테스트나 코딩, 흐름도 작성, 때로는 분석보다도 앞설 수 있다. 둘째, 기존 프로그램을 새로운 플랫폼이나 언어로 포팅하는 경우에서 보듯이 모든 단계가 항상 필요하지는 않다. 셋째, 각 과정을 꼭 일차원적으로 진행할 필요는 없다.

프로그래밍을 심리학적인 관점에서 연구하려면 이런 복잡한 행위들을 좀 더 간단한 단위로 분해해야 한다. 그러나 프로그래밍 과정은 순환적(또는 반복적)이므로 앞서 제시한 분류도 지나치게 정제한 것이다. 각 범주의 경계가 모호하거나 심지어 아예 구별되지 않기 때문이다.

실제로 프로그래밍 프로젝트를 명확하게 정의된 단계로 나누는 것이 가능하다 할지라도 그다지 바람직하지는 않다. 업무마다 필요한 재능이 다르고, 프로젝트에 참여한 프로그래머들은 각자 다양한 종류의 재능을 가지고 있다. 한 시기에 한 종류의 작업만 진행한다면, 그 외의 다른 재능들은 한동안 썩히는 셈이 된다.

따라서 작업을 여러 부분으로 분리하고, 각 부분 작업을 해당 단계에서 동시에 수행하는 편이 좋을 수 있다. 이렇게 하면 작업의 진척이 좀더 일정해지고 매일 변동될 프로그래밍 환경이나 프로그래머 컨디션에 영향을 덜 받을 것이기 때문이다.

예를 들어, 코딩이 매일 잘 되지는 않는다. 코딩을 하던 중에 일이 잘 풀리지 않음을 느낀다면, 코딩을 잠시 접어 두고 다른 종류의 기술과 마음가짐을 요하는 다른 작업에 눈을 돌리는 게 좋다. 그러나 그 시각에 해야 할 작업이 코딩뿐이라면, 일은 하면서 코딩에서 벗어날 방법이 없다.

실제로 작업하다 너무 하기 싫다면 문서화나 리팩터링을 통해 환기하는 것도 좋은 방법이라고 생각한다.

이 외에도 외부환경의 변화에 따른 작업의 단일화, 특정 단계의 고정으로 인한 과부화 등등의 단점이 존재하기에 이상적인 프로젝트는 반드시 인력을 동시에 몰아넣지 않아야 한다.

그러나 관리 메뉴얼을 문자 그대로 믿는 관리자는 이와 정확히 반대로 행동한다.

프로그래밍이란 이름 아래 행해지는 작업이 지닌 다양성으로 인해 프로그래밍에 대한 심리학적 연구 결과에는 어느 정도 과정이 섞이게 된다. 작은 프로그램을 개발하는 프로젝트의 성과를 실험하는 경우, 결과는 특정 작업 단계의 성과에 좌우된다.

프로그래머가 하는 작업들을 제대로 세분화해보면 전통적인 구분 간의 경계에는 분명 모호함이 있으나, 세분화해 보는 일 자체도 어느 정도 의미가 있다. 예를 들어 테스트 단계를 본다면 테스트라는 이름에는 적어도 세 가지 다른 행위가 포함되어 있음을 알 수 있다.

  • 버그의 존재를 인지
  • 버그의 발생 위치를 추적
  • 버그 수정

아주 넓은 의미에서, 이 세 가지 행위가 요구하는 기술과 개인 성격은 서로 다르다.

버그를 찾으려면, 완벽해 보이는 부분도 의심스럽게 바라보며 결점을 찾으려는 자세가 필요하다.

반면에, 버그의 발생 위치를 추적하려면 수도자의 끈기?와 동물적인 수집 본능?이 필요하다. 이런 추적하는 과정을 잘하는 사람이 존재할 수 있다.

하지만 버그를 잘 찾는 사람이 꼭 버그를 잘 수정하는 것은 아니다. (적절하지 않을 수 있다.) 버그를 프로그램에 적절한 방식으로 어느 정도 우아하게 수정하려면, 다른 특성을 지닌 프로그래머가 필요하다. 적응형과 균형감각…

정리하자면 버그를 찾는 사람은 분석적인 사고력이 필요한 반면, 수정하는 사람은 종합적인 사고력이 필요하다. 물론 한 사람이 두 가지 일에 모두 뛰어날 수도 있다. 그러나 그런 사람을 찾기 보다는 두 가지를 다 잘하는 팀을 찾는 편이 더 쉽다.

각 팀원의 소질과 단점을 인정하는 감각과 겸손함을 갖췄다면, 그 팀의 능력은 팀원 각자의 능력을 능가할 테니 말이다.

요약

프로그래밍은 획일적인 한 덩어리의 행위가 아니다. 소프트웨어 설계자들은 아마추어보다 프로가 더 다양한 도구를 필요로 한다는 사실을 자주 잊는다.

관리자들은 프로그래밍 작업의 단계가 명확하게 구분되지 않을 뿐더러 각 단계가 순차적으로 수행되지도 않는다는 점을 자주 잊는다.

프로그래밍의 다양한 성격 때문에 소프트웨어 설계자의 관리자, 프로그래머의 업무가 혼란스럽고 복잡해진다. 앞에서 좋은 프로그램에 대한 절대적인 정의를 내릴 수 없었듯이, 좋은 프로그래머나 좋은 관리자도 한마디로 규정할 수 없다. 심지어 좋은 소프트웨어를 정의하는 일도 쉽지 않다.

결과적으로, 프로그래밍에 관한 논의를 활성화시키려면 논의의 수준을 낮출 수밖에 없다. “무엇이 좋은 프로그래머를 만드는가?”란 주제에서 일반적으로 적용할 수 있는 결론을 얻으려면, 보통 논의되는 내용보다 훨씬 더 세부적인 면까지 고려해야 한다.

그리고 아마도 좋은 프로그래머를 만드는 요소가 훌륭한 우정을 만드는 요소와 비슷하다는 사실을 발견하게 될 것이다.

바로, 상호 관심과 개성 존중이다.

오래된 고전 책이라 업무에 있어서 시대차이를 느끼지만, 인간관계나 프로그래머의 본질적인 특성은 시대를 벗어나 획일적이라 느낀다.

논의사항

예를 들어, 코딩이 매일 잘 되지는 않는다. 코딩을 하던 중에 일이 잘 풀리지 않음을 느낀다면, 코딩을 잠시 접어 두고 다른 종류의 기술과 마음가짐을 요하는 다른 작업에 눈을 돌리는 게 좋다. 그러나 그 시각에 해야 할 작업이 코딩뿐이라면, 일은 하면서 코딩에서 벗어날 방법이 없다.

  • 코딩이 잘 되지 않는 날에 어떤 작업으로 눈을 돌리시나요?

8장 개인의 성격

어떤 의미에서, 성격은 사람들 사이에서 볼 수 있는 모든 개인차를 포괄하는 개념이다. 인간의 행동을 조금만 관찰해도, 지능과 교육 정도에 따라 성격의 차이가 생김을 명백히 알 수 있다. 이때의 성격은 어떤 사람을 다른 사람과 구별해 주는 개인적 특성을 총체적으로 일컫는다. 이런 의미에서 성격은 그 사람의 정체성이다.

미치광이 파괴자

프로그래밍 초보인 기술자는 프로그래밍 교육 과정을 수강하도록 조치해 문제를 해결할 수 있지만, 전문가에게 교육은 답이 될 수 없었다. 그에겐 프로그래밍의 모든 면을 정복했다는 절대적인 자부심이 있었기 때문에, 교육을 받거나 다른 사람의 조언을 들을려고 하지 않았다.

변하는 성격

성격을 보편적으로 정의할 수 없지만, 성격이 프로그래밍에 끼치는 영향을 연구할 때 다음의 정의를 기반으로 할 수 있다.

개인의 성격은 모든 특징을 하나의 유기체로 통합한 것으로, 끊임없이 바뀌는 주변 환경에 적응하는 과정을 결정하거나 또는 그 과정에 의해 변화된다.

성격이 고정적이지 않다는 점에 대해서 좀 더 부가적인 설명을 하자면, 분명히 성격은 잘 변하지 않는다. 그럴만한 이유가 없다면 성격은 변하지 않는다.

불행히도 성격이 바뀐 원인을 밝히는 것은 어렵다. 상냥했던 사람이 퉁명스러워졌다고 항상 치과에 가 보라고 할 수는 없다. 같은 양상을 보이는 성격 변화라도 원인은 다양할 수 있다. 육체적인 원인일 수도 있고, 심지어 완전히 외부적인 원인일 수도 있다.

개인의 성격에 관련된 문제가 생겼을 때 진짜 원인을 이해하지 않고서는 적절히 해결할 수 없다. 심리학적 지식이 그런 문제의 원인을 찾는 데 도움이 될 수는 있지만, 아무리 심리학에 정통해도 문제의 당사자가 입을 열지 않고서는 처방을 내릴 수 없다.

변하지 않는 성격

성격이 주변 환경의 변화에 적응하는 과정에서 변하는 것이라면, 성격의 변화를 그 사람이 속한 환경의 변화에 대한 신호로 볼 수 있다. 그러나 성격의 변화는 크든 작든 자주 있는 일이 아니다. 따라서 긴 안목으로 볼 때 더 관심을 가져야 할 부분은 프로그래머의 불변적인 성격이 그 직업 생활에 미치는 영향이다.

성격을 바라보는 일반적인 관점에 따르면, 성격은 그 사람이 가진 특질의 집합으로 볼 수 있다. 우리는 “이 사람은 보수적이고 착실하며 약삭빠르고, 저 사람은 숫기는 없지만 재치가 있다.”는 식으로 성격을 묘사한다.

그렇다면 이상적인 프로그래머가 가져야 할 특질을 만들 수 있을까?

그러나 좋은 프로그램을 정의하기 어렵듯이 상황에 따라 너무 다양하기에 정의할 수 있는 최선은 프로그래머의 특정 특질과 특정 프로그래밍 업무의 관계를 밝히는 것이다.

  • 의심이 많은
    • 단순 디버깅을 놓고 보자면 최고의 성격
    • 테스트 팀에서 유리
  • 잘 믿는
    • 협업에 있어서 유리

위 내용과 같이 성격에 따라 모순적인 상황이 나오기 때문에 모든 조건은 절대 같을 수 없다. 모순적인 상황을 얼마나 잘 참을 수 있느냐는 그 사람이 정서적으로 얼마나 안정되어 있으냐에 따라 다르다.

그 기간에 따라서 다른데 관리자가 업무 과제를 자주 바꿔 주면 테스트 담당자에게 필요한 엄격한 성격 조건을 완화해도 괜찮다. 비자아적 프로그래밍에서는 이런 업무 교대가 자동으로 이뤄진다. 아무도 자신의 특정 성격 때문에 무자비한 공격을 받지 않아도 되기 때문이다.

비자아적 프로그래밍에서 항상 자신의 성격에 최고로 잘 맞는 업무에만 투입될 가능성이 없다. 안정성을 위해 잠재적인 능률을 희생하는 셈이다. 그러나 잠재된 능률을 모두 잃는 것은 아니다. 처음부터 각자의 성격에 상관없이 아무렇게나 배치하지는 않기 때문이다. 그리고 다른 사람의 신발을 신어 보는 것은 참을성을 기르는 좋은 방법이다.

실제로 사람을 그 성격에 가장 잘 맞게 배치하려는 시도는 실패하기 쉽다. 성격은 표면적으로 보이는 부분이 다가 아니기 때문에 겉으로는 똑같아 보이는 성격도 내면은 다를 수 있다. (대부분은 다를 것이라 생각한다.)

우호적인 사람은 완전히 마음을 놓고 있는 편안한 상태임을 나타내는 것일 수도 있지만, 반대로 불안한 상황에 처해 자신의 인상을 좋게 하려고 노력하기 때문에 그런 성격으로 보이는 것일 수도 있다.

따라서 사람의 성격을 파악할 때에는 표면을 관찰하는 것에 그칠 게 아니라 어느 정도 내면을 추론하기도 해야 한다.

이런 성격을 추론하는 능력도 대부분 경험적인 스킬로 쌓아진다고 생각한다.

프로그래머에게 꼭 필요한 성격

성격을 측정하는 것은 어렵다. 그리고 특정 작업과 성격을 연결 짓기란 거의 불가능하다. 그렇다고 프로그래밍에 적합한 성격을 가진 사람을 고르는 방법이 전혀 없을까?

프로그래밍 업무를 수행하는 데 프로그래머의 성격이 중요한 요소라면, 포기할 수 없는 문제다. 일반적인 경우는 힘들겠지만, 극단적인 경우를 놓고 보면 뭔가 의미 있는 결론을 얻을 수 있을 것이다.

성격과 프로그래밍의 본질적인 관계는 복잡 미묘하여 한마디로 말하기 힘들지만, 어떤 프로그래밍 실패로 이어지는지에 대해서는 몇 가지 단언할 수 있다.

프로그래밍은 지능보다 성격이 더 중요하다고 단언할 수 있다. (인성평가가 있는 이유?)

누군가 프로그래머로 크게 성장할지도 모르는데 조건만 따져서 아예 기회를 주지 않는 것은 잘못된 일이다. 그러나 지능이 평균 이하인 사람이 프로그래머기 되는 것을 막는 효과는 있다. 따라서 어느정도 평가를 통해 막는 효과를 볼 수 있다. (가장 기본이 되는 코테)

그러나 그와 비슷하게 지원한 사람의 성격을 근거로 사람을 뽑는 절차가 있는가? 하지만 성격은 변하기 때문에 결과가 일정하지는 않을 것이다.

이러한 사항들에 대해 심리학자들이 말하는 것 중 정말로 믿을 만한 부분은 지능이 성격보다 환경의 변화에 덜 반응한다는 것이다.

그렇다면 프로그래머가 되면 실패할 확률이 높은 사람은 과연 어떤 성격의 소유자일까?

  • 실패할 확률이 높은 사람
    • 스트레스가 많은 상황을 오래동안 버티지 못하는 사람
    • 잦은 변화에 잘 적응하지 못하는 성격
  • 있으면 좋은 성격
    • 깔끔한 사람
    • 겸손한 사람
    • 유머감각..?
  • 양면
    • 자존감과 자신감의 분리

성격검사

융통성 없는 성격은 이상적인 프로그래머에게 적합하지 않다. 어떤 사람은 프로그래머가 정밀한 기계를 다뤄야 하므로 그 성격이 완고해야 한다고 믿는 것 같다. 하지만 실상은 컴퓨터가 융통성이 떨어지기 때문에 프로그래머는 오히려 융통성 있는 사고를 해야 한다.

실생활에 필요한 기능을 컴퓨터상에 구현하려면 프로그래머가 주입한 유연성이 필요한 것이다. 이러한 잘못된 세간의 믿음을 바로잡기 위해 프로그래머를 위한 성격검사법이 있으면 좋을 것 같지만 그것이 과연 가능할까?

현대의 대부분은 성격 장애를 찾아내는 데 목적을 둔다. (로르샤흐) 과연 모든 직업에서 지원자에게 정신병검사를 받도록 하는 행위가 과연 옳은가?

실제 기업에서도 어느정도 필요하다고 생각하지만, 직업의 귀천을 따지기 보다 잘 할 수 있는 수준으로 제한하는 게 좋다고 생각하긴 한다.

각 프로그래머의 유형에 따라 흥미 패턴이 있다 하더라도 이것은 해당 영역에 이미 종사하고 있는 사람들을 대상으로 조사한 결과일 뿐이고, 그 직업에 종사하기를 원하는 사람들을 조사한 결과가 아니다.

그러나 프로그래머라는 직업은 아직 걸음마 단계에 있다. 게다가, 고용자들이 평균적으로 자신이 채용한 프로그래머에 대해 만족하지 못하고 있다는 것은 어느정도 확실하다. 이런 상횡에서 현재의 프로그래머들을 미래의 프로그래머가 만족시켜야 할 모범 답안으로 살아야 하는가?

성격검사의 또 다른 문제는 피검사자가 속임수를 쓸 수 있다는 점이다. 성격검사를 비롯한 모든 심리검사는 검사를 고안한 심리학자가 검사를 받을 사람보다 똑똑하다는 가정을 전제한다. 만약 심리학 검사를 업으로 삼는 사람들을 대상으로 성격검사를 하면, 대체로 자신이 다른 사람보다 똑똑하다고 생각한다는 결과가 나올 것이다. 그러나 그들 스스로 그렇게 믿는다고 해서 사실이 되는 것은 아니다.

물론 심리학자들은 속임수의 가능성을 부정하거나 그 중요성 또는 빈도를 평가 절하할 것이다. 그러나 프로그래머들은 성격검사를 받을 때 실제로 속임수를 쓴다.

프로그래머에 대한 성격검사

앞에서 밝힌 성격검사의 문제점들은 염두에 두고, 프로그래머를 대상으로 실시한 성격검사의 결과를 살펴보면 다음과 같다.

  • 일반인에 비해 프로그래머는 진보적인 사람보다 보수적인 사람을 선호하는 정도가 크다고 한다.

“당신은 프로그래밍을 좋아합니까?”

요약

프로그래밍 업무는 매우 복잡하기 때문에 프로그래머로 성공하기 위한 요소 중 성격의 중요성이 보통 생각하는 것보다 훨씬 크다.

그러나 성격검사로 오떤 사람이 좋은 프로그래머가 될지 판별할 수는 없다. 그러기엔 검사법에 결함이 있을 뿐 아니라 프로그래밍 자체에 대한 우리의 이해도 깊지 않다.

너무 다양한 요건을 요구함.

하지만 특정 프로그래밍 업무에 필수적인 성격 요소를 추려낼 수는 있어 보인다. 어떤 성격의 소유자가 어떤 업무를 잘 하지 못할 것임을 알아내는 차원에서는 말이다.

결과적으로, 성격이라는 주제를 연구하면 프로그래머의 능률을 높이는 데 어느 정도 공헌하게 될 것이다.

논의사항

성격이 고정적이지 않다는 점에 대해서 좀 더 부가적인 설명을 하자면, 분명히 성격은 잘 변하지 않는다. 그럴만한 이유가 없다면 성격은 변하지 않는다.

  • 프로그래밍 분야에 들어와서 성격이 변하게 되신 경우가 있나요? 있다면 특정 경험에 대한 이야기를 듣고 싶습니다.

9장 지능 또는 문제해결력

겪어봐서 알겠지만, 프로그래머는 평균 이상의 지능을 가진 사람들이다.

과거에는 그럴 수 있을 수 있지만, 현대에는 그렇게 생각하지 않는다. 오히려 더 낮을 수 있다고 생각한다.

심리적 자세

잘못된 곳을 찾을 때에는 심리적 자세가 방해가 되기도 한다. 수많은 연구를 거쳐 사람의 눈은 기대한 면만 보는 경향이 있음이 증명됐다. (보고싶은 것만 본다.)

컴퓨터 프로그램에서 다양한 오류를 찾아낸다. 문법 오류나 잘못된 예약어, 잘못 선언된 상수 등은 간단하게 찾을 수 있고, 심벌 테이블이나 상호 참조 목록, 제어 흐름 분석은 상호 검증이 필요하다.

심리적 자세 외에 거리라는 개념도 염두에 둬야 한다. 어떤 단어를 다른 옳은 단어로 오인할 확률은 거리감으로 인해 단어마다 다르다. 읽은 사람이 지닌 심리적 자세와 관계없이 말이다.

그러나 프로그래밍 언어의 심벌에 대해서 거리를 그렇게 간단한 척도로 재면 어떤 심벌을 다른 것으로 오인할 확률에 대한 근사값밖에 얻을 수 없다.

자연어로 의미가 있는 심벌은 프로그램을 읽을 때 혼란스럽게 만들 여지가 특히 많다. 그 이유는 다음과 같다.

  • 사람들은 항상 의미를 찾으려는 심리적 자세를 가지고 있는데, 이를 자연어가 만족시키기 때문에 프로그램 자체에 어떤 의미가 있다고 보게 된다.
  • 사람들은 심벌의 값보다 심벌의 이름을 믿는 경향이 있는데, 그 경향을 더 부추긴다.
  • 심벌 사이의 적절한 거리를 유지하기가 어렵다.
  • 축약어로 인해 심벌 사이의 거리는 더 좁혀진다.

심리적 자세가 야기한 문제를 논할 때에는 주석문 예기가 빠질 수 없다. 코드에 주석을 다는 목적은 읽는 이가 코드를 직접 보기 전에 적당한 마음의 준비를 하게 만들려는 것이다.

그 코드가 정확하게 구현되어 있다면, 주석문은 확실히 효과가 있다. 그러나 코드가 부정확하다면, 읽는 사람의 심리적 자세가 주석문의 지배를 당하기 때문에 오류를 찾아내는 데 오히려 방해가 된다.

문제 해결의 여러 측면들

심리학에서는 심리적 자세를 지능보다는 인지의 일부로 본다. 그러나 앞절에서 봤듯이 심리적 자세가 문제 해결 행위에 영향을 줄 수 있음이 분명하다.

물론 심리적 자세는 문제 해결에 앞서 문제를 회피하는 데 영향을 준다. 문제를 모두 피하는 프로그래머가 문제를 안고 전전긍긍하는 프로그래머보다 지능적이다. 그 문제를 궁극적으로 해결하든 못하든 간에 말이다.

그러나 현실은 객관적인 척도가 부족하기에 프로그램 난이도를 판단할 때 담당 프로그래머가 얼마나 열심히 일 하느냐를 기준으로 삼곤 한다. 그 기준에 따르면 능력이 가장 떨어지는 프로그래머가 최고가 된다. 능력이 떨어지면 열심히 일하는 수밖에 없기 때문이다.

  • 더 능력있는 프로그래머가 피해를 입는 사례

가장 문제가 되는 경우가 문제 회피다. 물론 뭘 모르는 관리자를 속이려는 의도의 문제 회피는 그렇지 않지만?? 어떤 행위가 문제 해결에 얼마나 도움이 될지를 알기 어려운 것처럼, 우리가 얼마나 많은 어려운 문제를 회피하고 있는가도 알기 어렵다.

일단 문제를 해결하고 나면 그 전까지 겪었던 어려움은 완전히 잊기 쉽다. 문제 해결을 어렵게 만드는 가장 일반적인 원인 중 하나가 일부 요소를 간과하는 것인데, 일단 어떤 요소가 중요함을 깨닫고 나면 해결은 간단해진다.

만약 그 문제를 다른 사람에게 설명한다면 그 요소도 함께 설명할 터이고, 설명을 들은 사람은 앚은 자리에서 문제의 9할을 해결할 수 있을 것이다. 그는 우리가 왜 그렇게 어려워했는지를 이해할 수 없을 것이다. 마찬가지로 우리도 자신의 능력을 의심하게 된다.

심리적 자세도 일종의 가정하기다. 가정이 좀 더 깊이 묻혀 있는 경우이기는 하지만, 문제 해결에 영향을 미치는 것은 마찬가지다. 그렇다면 문제 해결의 첫 번째 원칙이 가정하지 않는 것이라고 할 수 있는가?

이는 맞는 말이면서 완전히 틀린 말일 수 있다. 문제를 성공적으로 해결하려면 가정을 하지 않을 수 없다. 모든 문제를 해결할 때마다 무에서 시작해야 한다면 문제 해결 능력이 향상되기는 불가능할 것이다.

가정을 전혀 하지 않기보다 주어진 문제에 맞춰 적절히 가정하는 편이 더 지능적인 행위다. 즉, 지능적인 행위가 모든 문제를 해결하는 마법의 공식을 제시하는 것은 아니다. 그보다는 여러 공식을 갖춰 놓고 특정 공식에만 집착하지 않는 쪽이 지능적인 행위다.

프로그래밍을 위한 지능의 여러 측면

모든 종류의 지능적 행위에는 융통성이 필요하다. 정신적인 행위일지라도 몇몇 고정된 규칙으로만 수행된다면 지능적이라 할 수 없다. 그런 행위는 사람보다 기계가 수행하는 편이 낫다.

그러나 지능적 행위에서도 몇몇 고정된 규칙을 적용하는 것은 중요한 요소다. (약점을 덮을 만한 다른 방도가 없다면 다른 프로그래머와의 경쟁에서 불리하다.)

사람들은 저마다 다른 고유의 문제 해결 기법을 갖고 있다. 사람마다 잘 하는 것이 다르기 때문에 사람들은 각자 자기 능력의 강약에 맞는 해결 기법을 고르고 한다.

  • 뛰어난 기억력을 가진 프로그래머의 예제
    • 기역력이 뛰어난 상황에 좋은 경우가 있을 순 있지만, 이는 상대적, 환경적인 요인이 너무 많아서 의지하는 것은 좋지 못한 것 같다. 테스트, 문서화를 통해 이를 해결

작업 환경에 따라 다른 형태의 지능적 행위를 취해야 하는 것과 마찬가지로 프로그래밍 단계에 따라 두각을 나타내는 프로그래머가 달라진다. (창의력과 선택 능력 중 어느 하나라도 부족한 프로그래머는 프로그램 설계 단계에서 능력을 발휘할 수 없다.)

적성 검사

프로그래밍에 지능이 그렇게 중요하다면 프로그래머가 될 사람을 어떻게 선별하는 것이 좋을까?

현대에는 코딩테스트로 대체한다.

그러나 이것도 이론적인 추측일 뿐이다. 아직 적성 검사 결과의 유효성자체가 검증되지 않았다. 프로그래머에 대한 적성 검사는 적성 검사에서 높은 점수를 받은 사람들이 프로그래밍 교육기관에서 좋은 성적을 낸 학생들이었다는 연구 정도가 유효성을 입증할 근거가 될 뿐이다.

과연 코테에서 좋은 점수를 받는 사람이 책에서 말하는 좋은 개발자일까?

기본적인 커트라인인 경우로 생각하는 것이 좋아 보인다.

프로그래머를 대상으로 하는 적성 검사

상관성을 측정할 수 있지만, 그 수치가 과연 정확한가에 대한 생각

상관성에 관한 글

스스로 경험이 있다고 주장하는 프로그래머에게 왜 잠시 앉아 작은 프로그램을 작성하거나 멍세서를 읽은 후 구현 스케치를 해보라고 시키지 않는가? 이는 아마도 우리 스스로도 프로그램을 거의 읽어 보지 않으므로 실제로 발생할만한 상황이 아니라고 생각하기 때문일 것이다.

또는 경력자를 뽑을 때 지원자가 한 명뿐이더라도 그 사람이 운 좋게 능력 있는 사람이기를 막연히 바라고 있기 때문일 것이다. 지원자가 한 명뿐일지라도 당신의 아내감을 고르듯이 해야 한다.

요약

프로그래머를 고용하는 데 관계된 사람들은 좋은 프로그래머에게 필수인 자질이 무엇인지에 대해 저마다 의견이 있다.

어떤 프로그래머를 뽑느냐보다 어떻게 프로그래머를 양성할 것인가로 바뀐다.

즉, 좋은 프로그래머는 태어나는 것이 아니라 만들어진다. 따라서 우리는 프로그래머의 생산 즉, 훈련 과정에 관심을 가져야 한다.

논의사항

프로그래밍에 지능이 그렇게 중요하다면 프로그래머가 될 사람을 어떻게 선별하는 것이 좋을까?

  • 기업에서 실시하는 코딩테스트에 대한 생각을 듣고 싶습니다.
    • 그냥 기본기로 면접을 볼 사람을 어느정도 거르기 위함인지
    • 책에서 말하는 지능적 수준을 보기 위함인지
    • or 다른 것을 보기 위함인지

10장 동기 부여와 훈련, 경험

심리학에 따르면, 어떤 과제를 해결할 때의 능률은 과제가 무엇인가, 수행하는 사람이 그 과제를 얼마나 잘 이해하고 있는가와 함수 관계에 있다. 또 성격이나 지능과 같은 개인차에 의해 능률이 달라진다고 한다. 그러나 능률을 실질적으로 향상시키는 요인은 성격의 변화나 지능의 향상이 아니라 훈련과 경험에 있다.

심리학은 엄밀한 과학이 아니다.

다른 요인으로는 설명할 수 없는 그 불가사의한 부분은 동기부여의 몫이다. 심리학자들조차 동기 부여가 실제로 존재하는지 확신하지 못하고 있음에도, 여러 책에서 이 주제를 다루고 있다.

그러나 교육이나 훈련에 대한 논의를 진행하기 위해서는 동기 부여를 어설프게나마 짚고 넘어가야 한다. 이에는 두 가지가 이유가 있다. 첫째, 만약 동기 부여로밖에 설명할 수 없는 부분이 실재한다면 그 영역은 훈련이나 교육을 통해서 접근할 수 없는 곳일 것이다. 둘째, 동기 부여가 훈련이나 교육 자체에 지대한 영향을 미칠 수 있다.

동기 부여가 되지 않은 사람을 가르치기가 얼마나 힘들지 상상해 보라. 반대로 스스로 동기가 있는 사람이라면 배우는 것을 막을 도리가 없을지도 모른다.

동기 부여

다음은 한 표준적인 심리학 교과서에 수록된 동기에 대한 글의 첫머리다. 내가 지금까지 본 동기 부여에 대한 설명 중 최고라고 생각한다.

인간 행동에 대해 수많은 연구를 해온 결과, 인간은 환경에 대해서 피동적인 존재가 아님이 확실하다. 인간은 어떤 자극에 반응하고 어떤 자극은 무시할지, 또 어떤 정보를 배우고 나머지는 버릴지를 스스로 결정한다고 말할 수 있다. 따라서 인간에게는 일종의 원동력이 내재한다는 가정을 세울 수 있다. 이 내적 원동력이 우리가 흔히 말하는 동기다.

프로그래머는 일하는 도중에 잠깐씩 다른 생각을 할 수 있다는 사실을 굳이 확인할 필요는 없다. 그런데 관리자는 프로그래머의 능률이 떨어짐을 동기의 부족이라고 단정해 버리는 실수를 많이 범한다.

그래서 관리자는 부족한 내적 원동력을 보충할 외적 동력을 프로그래머에게 부여하려 한다. 사실 프로그래머에게 동기가 적어서라기보다는 너무 많아 문제인 상황에서도 말이다.

동기에 대한 연구 결과 중 가장 널리 알려지고 인정 받는 것은 동력을 높이면 처음에는 능률이 최대치까지 올라가지만 그 이상의 동력을 가하면 오히려 능률이 0까지 빠르게 떨어진다는 점이다.

특히 과제가 복잡할수록 이러한 능률의 급등락이 많이 나타난다. 이는 프로그래밍에 매우 중요한 의미가 있다.

예를 들어 버그 찾기에 너무 열중하는 것은 좋지 않으며 심지어 아무 일도 하지 않는 때보다 더 나쁠 수도 있다. 그동안 수많은 버그들이 프로그래머가 포기하고 중압감을 떨친 후에야 잡혔다. 프로그래머에게 빨리 버그를 없애라고 압박하는 것은 최악의 전략이다. 그러나 이것이 지금까지 가장 일반적인 전략이었다.

프로그래밍 관리자가 동기 부여에 대해 가장 먼저 품어야 할 의문은 프로그래머가 현재 얼마나 많이 동기 부여가 되어 있느냐다.(자신도 마찬가지) 그리고 그 답에 따라 동기를 더 부여해야 할지 또는 오히려 줄여야 할지를 결정해야 한다. (균형잡기)

지나치게 동기 부여가 되어 있는 상황이라면 프로그래밍 프로젝트가 압력을 못 이기고 침몰할 가능성이 높다.

이제 동기를 더 부여해야 할지 줄여야 할지를 결정했다면 구체적인 방법은 무엇일까?

개인의 처지에서는 아마도 방법이 없을 것이다. 스스로 그렇게 할 동기가 없는데 자신의 내적 원동력을 어떻게 바꿀 수 없기 때문이다. 그러나 실제로는 관리자와 비슷한 전략을 쓸 수 있다. 내적인 뭔가를 바꿀 기회를 만들기 위해 외부 환경을 바꾸는 것이다.

몇가지 실험을 통해 어떤 외적 요인들이 프로그래머에게 동기를 부여하는지를 알아본다.

가장 많이 선택한 항목은 급료 인상 또는 보너스였다. 그 뒤를 쫓는 2위는 업무를 계획하는 데 관여한 정도였고, 승진, 과제의 질을 좀 더 높일 수 있는 추가 시간 부여가 공동 3위였다.

최하위는 내 업무의 범위를 줄이는 것 이었는데, 누구나 전체 계획에 좀 더 많이 관여하고 싶어한다는 사실에 비춰볼 때 이해할 수 있는 결과다.

반대로 적은 선택을 받은 항목은 문서화, 복사 등등에 대한 보조 인력이었다. (지금은 완전히 대체 가능하다고 생각) 두 번째는 높은 지위였는데, 이는 승진이 많이 선택된 점을 볼 때 의아한 결과였다.

그러나 이후의 또 다른 실험을 한 결과 사람들의 관념 속에는 승진이 새 직함을 얻는다기보다 급료 인상과 더 강하게 연결되어 있다는 사실이 밝혀졌다.

나머지 두 가지는 완료 목표일을 느슨하게 설정하는 것완료 목표일을 정확하게 설정하는 것이었는데, 이들이 모두 하위권이라는 점은 뭔가 이상했다. 설문 조사를 실시할 당시는 응답자들이 진행하는 프로젝트의 데드라인이 6개월도 넘게 남아 있던 것이다. (즉, 환경적인 사항이 실험에 영향을 크게 준 것)

이런 점이 동기를 연구하는 데 겪는 또 하나의 큰 어려움이다. 설문 조사를 통해 외적 요인들이 끼치는 실제 영향력을 밝혔다고 해도, 그것은 특정 시기의 특정 환경에서만 유효한 결과다.

돈은 저축과 급료가 늘고 갚을 빛이 점점 줄어들수록 그 중요성이 작아진다. 심지어 앞서 나온 일화와 같은 상황에서는 더 많은 돈으로 인해 직장을 떠날 수도 있다. (실제 스터디원들의 이야기도 동일했다.)

따라서 돈이 동기 부여의 요인으로는 다른 것들에 비해 실질적이지 못하다고 말할 수 있을까?

돈은 동기 부여에 대해 모호한 요인으로 볼 수 있다. (연구로 증명된 것이 없다.)

돈이 상징적인 의미를 주는 경우라면 그 프로그래머에게 동기를 부여하기 위해서는 추가 시간을 준다든가, 프로젝트를 계획하는 데 좀 더 많은 발언권을 준다는 식으로 볼 수 있다.

즉, 업무 자체가 프로그래머의 가장 큰 동기가 되어야 한다.

훈련과 수업, 교육

누구나 훈련을 거친다면 경쟁력 있는 프로그래머가 될 수 있는가?

교육 과정에서 생기는 혼동은 크게 두 가지로 나뉘는데, 하나는 수업과 교육을 혼동하는 것이고, 다른 하나는 교육과 훈련을 혼동하는 것이다.

  • 운영체제를 다루어 본 경험이 없으면 개념은 공허할 뿐이라는 사실
  • 특정한 훈련을 선행하지 않은 교육은 불가능하다는 점 (각자 필요한 경험을 컴퓨터에서 얻어낼 수 있는 상황을 만들어 줘야 한다.)

학습을 저해하는 요인들

의외로, 학습에 방해되는 요소가 있어서 배움에 실패하는 경우가 많다. 이때 의외라는 표현을 쓴 이유는 누군가를 가르칠 때 학습의 효과를 극대화하기 위한 각종 방책을 도입하는 것이 일반적이기 때문이다.

그런데 어린 아이가 학습하는 모습을 관찰해 보면, 그런 인공적인 환경 밖에서 훨씬 많은 것을 배운다는 사실을 알 수 있다. 우리가 원하는 형태로 아이가 학습하도록 조절하려면 의도적으로 벽을 만들고 문을 뚫어야 한다.

야생학습의 필요성.

우선 뭔가를 배우려면 알 만한 가치가 있는 것 중에서 아직 모르는 것이 존재한다는 사실을 인정해야 한다. 그런데 전문 프로그래머들은 그 사실을 인정하면 자신의 지위가 낮아진다고 여긴다. 진정한 프로라면 약점을 인정해도 잃을 것이 없음을 알고 있겠지만 말이다.

어떤 사람들은 약점을 가까스로 인정한다 해도 자신이 실패할 거라고 확신해 버리고 배우려 하지 않기도 한다. 그런 두려움은 자신감이 부족하기 때문이거나 비슷한 종류의 시도에서 실패한 경험이 있기 때문이다. 그러나 대부분 두려운 것은 실패 그 자체가 아니라 다른 사람들에게 자신이 실패하는 모습만 보이는 것이다.

어떤 경우에는, 그룹의 특성상 새로운 학습이 원천적으로 금지되고 이미 알고 있는 기술을 얼마나 잘 발휘하는지만 중요할 수 있다. 배우려면 실수에 관대해야 하는데, 관찰자가 존재할 때에는 그러기 어렵다. 따라서 작업자와 관찰자가 모두 잘 알고 있는 사안을 처리할 때 작업자는 늘 하던 방식을 택할 수밖에 없고, 결국 새로운 배움은 불가능하다.

  • 새로운 언어의 학습에 경우엔, 스스로 제한을 두는 (몰입 그래프)

다양한 프로그래밍 언어와 시스템에 대해서는 많은 논쟁이 있다. 그러나 배우기 쉬움과 사용하기 쉬움을 구별하여 다루는 논쟁은 거의 없다. 어떤 기능이 배우기 쉽다고 해서 사용하기에도 가장 쉽다는 법은 없다. 중요한 것은 기술의 확장성이다.

다시 말해, 그 기술을 처음 배울 때 적용했던 상황 외의 다른 상황에도 쉽게 적용할 수 있는가의 문제다. 일반론적인 기술을 하나 배우는 것은 지식의 목록에 한 항목이 추가되는 것 이상의 효과가 있다.

너무 특수해서 확장성이 전혀 없는 기술은 끝이 막힌 기술이라 할 수 있다.

프로그래밍에서 일정 규모의 문제들을 성공적으로 해결해 왔지만 그 규모를 넘어서는 문제는 제대로 해결하지 못하는 프로그래머를 심심치 않게 볼 수 있다.

그리고 반대의 경우도 꽤 있다. 규모가 큰 문제만 잘 해결하는 프로그래머도 있는 것이다.

어떤 끝이 막힌 기술 또는 프로그래밍 언어에 숙달된 프로그래머가 새로운 기술을 배우려면 잠시나마 현재 맛보는 만족감 중 일부를 버릴 각오를 해야 한다. 새 기술을 배우는 초기에는 시행착오가 많을 테고, 그럴 때마다 마치 예전의 초보자 시절로 돌아가는 듯한 느낌을 받을 것이다. 이런 상실에 대한 두려움은 새로운 프로그래밍 언어를 배울 때 특히 클 수 있다.

새로운 것에 대한 두려움과 실패에 대한 걱정, 자신의 약점을 인정하고 싶지 않은 마음에서도 마찬가지다. 그 외의 문제들은 간접적인 영향을 미치는데, 대부분 무엇을 배울지 또는 어떻게 배워야 할지를 잘못 이해해서 생기는 문제다.

프로그래밍 학습에는 대부분 교사가 없다. 교수 뿐만 아니라 학습에 필요한 필수인 요소들 또한 없다. 교과서도 참고서도 없으며, 소프트웨어를 실행할 하드웨어도 없다. 새 주제를 공부할 여유 시간도, 실제 상품에 적용할 신기술을 인증해 줄 권위자도 없고, 심지어 좀 더 경험이 많은 선배 프로그래머도 없다. 그런 요소가 없음으로 인해 학습은 지지부진해지고, 학습자는 첫 번째 고비에서 바로 포기하게 된다.

마찬가지로 대학에서도 나는 학문을 가르치는 것이 맞다고 생각하긴 한다. 대학에서 취업하는 방법을 가르친다고 한다면 학원과 다를 것이 없기 때문에 학문에 중점을 둬야한다고 생각한다.

학교는 배우는 곳, 직장은 일하는 곳이라는 생각은 꼭 프로그래밍 분야에 국한된 문제는 아니지만, 프로그래밍 분야는 어떤 분야와 비교해도 지속적인 학습이 중요한 분야이다. (천장이 없음)

프로그래밍을 학습하는 방법

스스로 발전하려 하는 프로그래머는 정식 훈련과 그가 필요한 교육을 받을 수 있도록 해주는 관리자의 배려에 의존하지 않을 수 없다. 순수하게 경험에만 의존하면 안 되는데, 경험한다고 반드시 뭔가를 배우는 것은 아니다.

프로그래머는 자신이 경험한 것을 배움으로 발전시키려면, 학습하는 방법을 배워야 한다. (야생학습)

  • 무엇을 모르는지 배우는 것이다. (레빗홀에서 빠져 나오는 것, 메타인지)
  • 학습자의 성향에 따라 분류
    • 직접 해보거나, 다른 사람과 교류를 통하거나
    • 새로운 프로그래밍 언어를 예로 직접 작성해보고 분석하는 단계에서 다른 사람과 토의하는 것
  • 물리적 환경을 조성
  • 피드백 (멘토, 정확한 정보)
  • 능동적인 태도 (스스로 의문하는 과정)
  • 프로젝트 중심

요약

우리는 프로그래머의 성과를 향상시키는 데 두 가지 측면에서 영향력을 행사할 수 있다. 하나는 일을 하고 싶어하는 마음이고, 다른 하나는 업무를 수행하기 위해 필요한 지식이다.

전자를 동기부여, 후자를 훈련 또는 교육이라고 한다. 그러나 프로그래머가 어떤 상황에서 더 열심히 일하는지에 대해 알려진 바는 거의 없다.

앞 내용에서 언급했듯이 프로그래머는 매우 다양한 스킬을 요구하기 때문에 개개인의 목적이 다를 것이다. 돈, 직급, 명성, 자아실현 등등.. 그런 목표에 다가갈 수 있을 때, 더 열심히 하지않을까?

프로그래밍 교육이란 주제에 대해 현대는 어느정도로 달라졌는지 궁금하다. 개인적인 생각으론 과거와 다르게 많이 발전했다고 생각한다.

정규교육에서 벗어나지 못했다고 하는 부분도 시간이 몇십년이 지났지만 지금도 크게 달라진 것 같지는 않다.

논의사항

지나치게 동기 부여가 되어 있는 상황이라면 프로그래밍 프로젝트가 압력을 못 이기고 침몰할 가능성이 높다.

  • 경험이나 상상을 통해서 어떤 상황이 과도한 동기에 의한 침몰 사례가 될 수 있는지 이야기 해보고 싶습니다.

제가 이해한 바로는 처음부터 너무 큰 작업을 하려고 한다던가, 과도한 예측치 등등이 될 것 같습니다.

4부 프로그래밍 도구

나만의 언어를 사용하는 것은 상당한 자율성을 누릴 수 있지만, 그보다 더 중요한 점은 내가 쓴 내용을 모두가 이해할 수 있어야 한다는 것이다. 그렇기에 표현에 사용하는 언어도 모든 사람이 이해할 수 있는 언어여야 한다.
버트런드 러셀

11장 프로그래밍 언어

프로그래밍 언어에 대한 수많은 논문은 있지만 그에 비해 심리학과 관련괸 내용은 찾기 힘들다. 미래의 컴퓨터를 상상하며 시간을 보내는 사람들 말고, 주어진 프로그래밍 언어를 써야만 하는 일반적인 사람에 대한 고려가 없는 것이다.

시대가 발전함에 따라 기계는 계속 변화하지만, 사람은 그대로이다.

따라서 프로그래밍 언어란 무엇인가를 이해하려고 노력하는 것보다 사람을 먼저 고려하고 기계와 수학을 나중으로 미루는 것이 더 중요하다. (심리학에 영향이 있는 부분만 다룰 것이다.)

프로그래밍 언어에 대한 논의는 언어란 무엇인가 그리고 언어에 있는 여러 의미를 고려할 때 프로그래밍 언어를 어느 선까지 언어로 볼 수 있는지를 살피는 것 시작한다.

언어 설계는 대부분의 일반 프로그래머들과 별로 관련이 없으므로 일반적으로 더 필요성이 큰 문제인 기존의 프로그래밍 언어 가운데 어떤 것을 선택할지에 집중할 것이다.

프로그래밍 언어와 자연 언어

모든 사람이 전문가인 분야가 하나 있다면, 그것은 언어다.

프로그래밍 언어라는 개념은 프로그래밍이라는 개념 자체와 함께 탄생한 것이다.

프로그래밍 언어라는 개념의 뿌리가 너무 깊으므로 프로그래밍 언어가 진짜 언어가 아님을 증명하려는 시도는 너무 현학적인 일일 것이다. 언어라는 것은 우리가 그렇게 부르면 언어인 것이다.

  • 프로그래밍 언어가 다른 언어와 다른 점
    • 말하기 언어와 비교
      • 음성 청각 통로
        • 기본적인 언어는 입을 통한 발성으로 송신하고 청각으로 수신한다. (다른 신체 기관을 사용하여 다른 행동이 가능)
        • 프로그래밍 언어는 문자 언어로 뒤를 받쳐 주는 말하기 형태가 없다는 점, 말하기 형태가 존재하지 않음으로 필기구 없이 대화가 힘들다.
      • 빠른 소멸
        • 기본적인 언어의 소멸과 다르게 프로그래밍 언어는 사라지지 않는다. (때로는 빠른 소멸이 있는 것이 편리하다.)
      • 다방향 송신, 일방향 수신
        • 이는 내뱉은 말은 거의 모든 방향으로 동시에 퍼져가지만 들을 때는 말이 어떤 방향으로 부터 오는지 식별할 수 있다는 뜻이다.
        • 프로그래밍은 완전히 다르며, 기도와 비슷하다. 다시 말해, 한 방향으로 송신하고 모든 방향에서 수신한다.
      • 상호 교환성
        • 사람과 사람은 같은 언어로 대화하는 반면, 컴퓨터는 서로 다른 언어를 사용한다.
        • 책에서 말하는 교환성은 아마 중간 컴파일러를 말하는 듯 하다..? (JIT)

한 번쯤 자신의 프로그램을 미적 대상으로 생각해 보지 않은 프로그래머는 진정한 프로그래머라고 할 수 없다.

겉으로는 실용적인 것이 최고라고 하지만 마음속 깊은 곳에서는 모든 프로그래머가 프로그램이 단지 작동하는 것만으로는 충분하지 않으며 다른 여러 측면에서도 옳아야 한다고 생각한다. 나중에 언어의 설계와 프로그램 테스트를 논의할 때 프로그램의 미학적 가치와 실용적 가치 사이의 연관 관계가 우연이 아님을 보게 될 것이다.

매우 매우 동의한다. 간단하게 가독성을 예로 네이밍을 중요하게 생각한다면 해당 클래스가 한 가지 책임 이상을 가진다면 그 만큼 네이밍이 모호해지거나 and가 들어가는 등 미학적으로 거리가 멀어진다. 이는 SRP와 연관되어 책임을 한 가지만 지는, 유연해지는 것과 직접적인 연관성이 있다.

“아름다움이 진리이며, 진리는 아름다움이어라.”

프로그래밍 언어 설계

일반적으로 우리는 새로운 언어를 배운 다음에야 현재 사용하는 언어의 단점을 명확하게 인지할 수 있다. 머릿속에 자리 잡은 프로그래밍 언어의 표준은 계속 변하고 만약 언어를 설계한다면 이를 반드시 고려해야 한다.

세상의 다른 표준은 거의 변하지 않지만 프로그래밍 표준만 계속해서 변화하는 이유는 기계의 경직성과 그에 따른 프로그래밍 언어의 경직성에 있다. 새로운 기계와 마주친 사람은 자신이 원하는 것과 지금 눈앞에 존재하는 것 사이의 간극을 좁히려 할 텐데, 그러려면 자신을 기계에 맞추든가 아니면 기계를 자신에게 맞추는 수밖에 없다.

기계, 특히 컴퓨터를 변화시키는 일도 가능하지만, 그렇게 하는 데 걸리는 시간은 보통 우리가 기계에 맞추는 데 걸리는 시간보다 훨씬 길기 마련이다. 어떤 의미에서는 컴퓨터를 인간의 성향과 한계에 더 잘 들어맞도록 우리에게 맞추려는 시도가 바로 프로그래밍 언어라 할 수 있다.

기계가 경직된 만큼 그 기계를 성공적으로 사용하려는 사람은 더 유연해져야 한다. 이 현상을 두고 인본주의자들은 비인간화라 생각하는지도 모르겠다. 일반적인 인간관계에서는 반드시 주고받는 것이 있어야 하기 때문이다. 한 쪽은 주기만 하고 상대는 받기만 하는 관계는 완전한 인간관계가 아니며, 양쪽의 인간성을 왜곡하는 결과를 낳기 쉽다.

우리는 어떤 프로그래밍 언어에 익숙해져 갈수록 그 언어에 점점 얽매이게 된다. 그 이유는 대부분 그 과정에서 너무 많은 투자를 했기 때문이다.

이는 사람은 현재 상황이 주는 고통이 아무리 크더라도 상황을 바꾼 후 결과가 확실하지 않다면 그냥 참고 안주한다. 프로그래머가 프로그래밍 언어를 배울 때도 마찬가지다. 첫 번째 언어를 배울 때 즉, 그가 아직 어떤 언어에도 투자한 바가 없을 때에는 아무런 문제가 없다.

그러나 두 번째부터는 얘기가 다르다. 이미 익숙한 언어를 사용할 때는 누리는 편안함을 버리고 낮선 언어를 사용하면서 겪게 될 고난을 선택하기란 쉽지 않다. 그 고난을 이겨 낸 후의 보상이 명백하지 않은 한 말이다.

만약 특정 언어에 종속되지 않은 범언어적인 원리들을 밝히고 가르칠 수 있다면, 그래서 초보자까지도 새로운 언어를 배울 때 그런 일반적인 척도를 기준으로 삼을 수 있다면, 위와 같은 상황이 나아질 수 있다. 그러나 오늘날 대학 등의 교육 현장은 정확히 반대로 가튼 것 같다.

지금도 그러하다는 것이 굉장히 신기하고, 이유가 궁금해지기도 한다.

원리를 가르치지도 않고, 대조적인 두 언어를 동시에 가르치는 일도 없다. 또 언어를 가르친다 해도 프로그래밍의 여러 측면을 폭넓게 보여줄 수 있는 언어를 택하면 좋을 텐데, 보통은 간단하고 작위적인 언어를 택한다. 이는 학생들에게 프로그램을 작성할 능력을 최대한 빨리 심어 주려는 목적이며 프로그램의 종류는 상관하지 않는다는 뜻이다. 물론 전혀 가치가 없다고 말할 순 없지만 학생이 프로그래머로 성장하는 데 한계를 긋게 될 가능성이 있다.

프로그래밍 언어의 심리학을 이해하려면, 프로그램을 읽는 것 이상이 필요하다. 프로그램이 작성되는 과정을 관찰해야 하며, 프로그래머를 직접 면담해야 할 수도 있다. 그러나 사실은 그렇게 해도 전부 파악할 수는 없다. 직관적으로 금방 파악할 수 있는 것 이상을 얻으려면, 다양한 경로를 통해 다양한 정보를 축적해야 한다.

이렇게 일이 복잡한 까닭은 프로그래머 자신조차 자기 행동의 이유을 명확히 알지 못하는 경우가 많은 탓이다. 이는 인간 행동을 다루는 모든 연구에서 공통적으로 겪게 되는 걸림돌이다.

심리학적 관점에서 프로그래밍 언어나 기계를 평가할 때는 나쁜 프로그래밍에 대한 책임을 서툰 프로그래머에게 모두 전가하는 손쉬운 길을 택해서는 안 된다. 앞서 다룬 환경의 공통적인 요소처럼 프로그래머가 언어를 배우는 과정에선 종합적인 요소를 평가하고 코스트를 체크해야 한다.

이상적인 프로그래머가 실재한다면 프로그래밍 언어가 필요가 없을 것이기 때문이다.

요약

프로그래밍 언어를 언어로 취급하는 사고방식으로 인해 인간과 기계의 의사소통이 진보하지 못하고 있다. 어떤 것을 언어라고 부른다고 진짜 언어가 되는 것은 아니며, 오히려 잘못된 편견을 가지게 됨으로써 결국 엉뚱한 방향으로 연구가 진행된다.

프로그래밍 언어가 진보하려면, 성배(은총알)를 찾으려는 즉, 프로그래밍을 위한 진짜 언어를 찾으려는 노력을 그만둬야 한다. 프로그래밍 언어는 절대로 인간의 언어와 같을 수 없기 때문이다. 우리가 추구해야 할 것은 프로그래밍 언어를 더 자연스럽게 만드는 일이다.

다시말하자면, 컴퓨터를 잘 사용하기 위해 우리의 생각하는 방식을 바꾸고 있는 중인지도 모른다. 그렇게 하면 안 될 이유가 있을까? 인간의 다른 발명들도 모두 인간을 바꿔놓지 않았던가?

세월이 흐르면서 생각보다 많은 프로그래밍 용어와 개념들이 일상에 들어왔다. (추상적이였던 개념을 잘 설명하기 위한 좋은 단어)

논의사항

  • 프로그래머로써 일을 하게 되면서 특정 언어에 깊이를 가질 수 밖에 없다고 생각되는데, 다른 언어를 학습할 때 자신만의 방법이 있나요?
    • 저는 게임쪽이라 C/C#/C++에 한정되어 있긴 해서 대부분 비슷한 틀을 따라가는 것 같긴 합니다. 다른 언어를 학습할 땐 현재 언어와 차이점을 위주로 비교해가면서 익숙한 개념들로 배워가는데, 전혀 다른 언어를 학습하게 될 때는 과연 어떤 방식으로 접근해야 할지 궁금합니다.

12장 프로그래밍 언어 설계에 필요한 원칙

일관성

프로그래밍 언어에서 어떤 면을 어렵게 느낄 것인지에 대한 경험 자료를 가끔 일반 심리학의 연구 결과에서 찾을 수 있다. 바로 일관성의 원칙이다.

일반 심리학 연구 결과에 따르면 어떤 목록을 얼마나 잘 기억할 수 있는가는 그 목록에 담겨 있는 정보의 내용과 밀접한 관련이 있다고 한다. 그런데 이때 정보의 내용이란 그 사전적 의미처럼 단순하지 않다. 목록에 포함되어 있는 것뿐만 아니라 목록에 있지 않지만 그 목록을 기억해야 하는 사람의 머릿속에 들어 있는 것도 정보의 내용에 포함되기 때문이다.

000 001 010 011 100 101 110 111

000 001 010 100 101 111

위 이진수 목록보다 아래 이진수를 더 외우기 어려울 수 있다. 이는 앞서 말한 이진수 체계에 대한 정보의 기반으로 외우기 때문이다. 즉, 목록에서 빠진 항목이 얼마나 많으냐가 외우기 어려운 정도를 결정하기 때문이다.(외워야 할 정보의 증가)

반대로 이진수 체계를 모르는 사람일 경우는 달라진다. 다른 사람의 눈엔 일련의 난수로 보이기 때문이다.

이와 같은 현상은 프로그래밍 언어에서도 자주 발생한다.

예로는 람다, 최신 기능의 적용 (C#의 경우 is not)을 예로 들 수 있을 것 같다.

프로그래밍 언어의 일관성을 굳이 한문장으로 정의하자면 “동일한 표현은 그 위치와 상관없이 동일하게 동작한다. “프로그래밍 언어가 이 원칙에서 멀어질수록 배우기가 어렵고 프로그래머가 오류를 범할 가능성도 커진다.

앞서 말한 일관적이지 못한 문법은 프로그래머가 여러 가지 의미론적인 시도를 하는 데 장애물이 된다. (이는 협업자간의 컨벤션이 통일되어야 함을 의미한다.) 예외가 너무 많아 프로그래머가 스스로 그 언어에 정통했다는 자신감을 갖기가 어렵기 때문이다. (자신이 알고 있는 지식과 충돌)

이런 충돌을 회피하기 위해선 한 가지 언어에 대한 깊이가 있다면 다른 언어를 학습할 때 차이점을 두고 공부하는 것이 효율적이라는 생각이다. 최근 C#에서 C++넘어가야 하는 일이 있었는데, 알고있는 지식을 활용한 학습법이 가장 효과가 좋았다.

모든 원칙에 탄탄한 근거가 뒷받침되는 것은 아니며, 그렇게 근거가 빈약한 원칙일수록 검증하기 않고 슬그머니 넘어가곤 한다. 그중 대표적인 것이 명확성의 원칙이다. “모든 언어에는 반드시 문자 집합과 명확하고 결정력 있는 문법이 있어야 하기 때문에…”

포트란의 예제 말고도 유행하는 수학 문제?의 논제도 명확성의 문제로 보인다. (n = 8 / 2(2+2)) 다만 이는 프로그래밍 영역이 아닌 수학에 대한 인지적인 부분.

또한 이런 명확성에 관련된 프로그래밍 영역의 문제는 IDE가 발달하면서 대부분은 체크가 되는 것 같기도 하다.

간결성

인간의 정신에 선천적인 용량의 한계가 있음을 언급했다. (이는 LTM, STM정도로 생각해도 좋을 것 같다.)

우리는 단어를 사용하는 습관이 있다. 다른 연구를 통해서도 우리의 사고 과정에서 단어로써 치환 과정이 쉽게 일어남을 확인할 수 있다. (이는 청크와 추상화 개념에 대한 설명)

심리학에서는, 여러 작은 단위를 조합하여 커다란 단위 하나로 묶고 그렇게 만들어진 큰 단위도 각각을 구성한 하위 단위와 마찬가지로 쉽게 다루는 인간의 정보 처리 능력을 의미덩이 만들기(chunking)라 부른다.

프로그래밍 언어의 설계자가 활용할 수 있는 의미덩이는 제한되어 있다. 프로그래머가 그 언어를 사용하기 전부터 이미 알고 있거나 그 언어를 사용하면서 바로 익힐 수 있음 직한 의미덩이들만 가능하다. 그러나 동일한 것을 여러 방법으로 표현하는 수단을 제공하여 프로그래머에게 그 이상의 의미덩이를 사용할 기회를 줄 수 있다.

글을 쓸 때는 정보를 중복함으로써 얻어지는 효과부터 부담이 더 큰 편이기 때문에, 프로그래밍 언어에서 잘 만들어진 디폴트 체계는 충분한 가치가 있다.

근접성과 순차성

잘 설계된 프로그래밍 언어는 좋은 기억력과 마찬가지 방식으로 프로그래머를 도와준다. 즉, 관련된 정보를 쉽게 찾을 수 있는 곳에 담아 두는 것이다.

이에 관련하여 우리가 관심을 가져야 할 기억력과 종류에는 두 가지가 있다. 바로 공감각적 기억력순차적 기억력이다.

  • 공감각적 기억력은 특정 세부 사항에 의지하지 않고 얼굴이나 이웃, 책 한 페이지의 편집 배치 등을 알아볼 수 있게 해주는 능력이다.
  • 순차적 기억력은 청각을 통해 들은 정보와 좀 더 밀접하게 관련되어 있다. 인간의 순차적인 기억은 마치 차례로 이어진 사슬처럼 구성되어서, 차례로 떠오르면서 고리마다 바로 다음에 오는 고리를 상기시키는 구조인 것 같다. (링크드 리스트)

프로그램에서 근접성의 개념은 공감각 기억에, 순차성의 개념은 순차적 기억에 대응한다. 근접성은 프로그램에서 서로 관련 있는 부분이 모두 한 장소에 나타나는 성질을 의미한다. 근접성이 좋지 않으면, 소스코드를 가지고 작업하는 프로그래머는 지금 페이지와 관련 있는 다른 페이지의 내용을 모두 기억할 수 있을 정도로 공감각 기억력이 뛰어나지 않는 한 계속 여러 페이지를 봐야한다.

프로그래밍 언어에서 근접성을 높이는 방법 가운데 하나는 압축이다. 극단적으로 얘기해서, 전체 프로그램이 한 페이지에 들어간다면 당연히 관련 있는 모든 부분이 그 페이지에 모여 있을 수밖에 없다.

책에서 말하는 과거 사례에서 볼 수 있듯이 코드가 더 유연하고(예술적) 논리적으로 변경되어야 하는 이유를 알 수 있다.

전통과 혁신

실수할 가능성은 최소로 줄이면서 쉽게 표현할 수 있으려면, 프로그래밍 언어가 자연스러워지는 것이 가장 필요하다. 자연스러움은 앞서 보았듯이 일관성을 통해서도 얻을 수 있지만, 이는 이미 그 언어에 어느 정도 경험이 쌓인 프로그래머들에게만 효과가 있다.

어떤 언어를 처음 첩할 때에 일관성을 인식하기는 어렵다. 오히려 프로그래머가 이미 지닌 기준에 의해 이상하다는 느낌을 받게 되기 쉽다.

객체지향 언어가 점점 서로를 닮아가는 과정이라 생각된다.

프로그래밍 언어가 자연어와 비슷해질 수 있는 영역으로는 철자법도 있다. 자연어로 씨은 글을 읽을 때, 우리는 종종 철자법이 틀려서 심지어 전혀 말도 안 되는 다른 단어로 바뀌는 경우에도 그 사실을 의식하지 못하고 넘어가곤 한다. 말할 때에는 당연히 철자법으로부터 더더욱 자유롭다.

반면에, 프로그래밍 언어는 대부분 의도가 무엇인지 뻔한 경우까지도 오류로 감지할 정도로 철자법에 대해서 극히 엄격하게 대처한다. 축약어도 어떤 단어의 또 다른 철자다.

프로그래머들은 저마다 너무 다르기 때문에, 프로그래머가 이미 아는 개념이나 구조에 새로운 언어를 부합하도록 만드는 데는 분명한 한계가 있다. 숫자 리터럴이나 단순한 산술 연산 같은 형식은 모든 프로그래머가 다 익숙하리라 예상되지만, 사람마다 제각기 선호하는 방식이 다르다는 문제에 봉착하는 건 시간 문제다.

같은 사안에 대해 가능성을 두 개 이상 제공하면 즉, 언어를 느슨하게 만들면 개인의 성향에 좀 더 맞춰 줄 수 있다. 어떤 의미에서 보면 느슨한 언어는 프로그래머 개인의 선호에 대한 적응성이 뛰어나다고 할 수 있다.

느슨함 외에도 언어의 적응성을 높이는 방법에는 여러 가지가 있다. 특정 프로그램 또는 모든 종류의 프로그램을 위한 새로운 뭔가를 만들 수 있도록 해주는 기능이 이에 해당한다. 함수 또는 하위 루틴을 정의할 수 있는 기능이 대표적인 예다.

최근에는 거의 모든 언어에서 지원하는 기능이라 생각한다.

특수 목적 언어, 범용 언어, 장난감 언어

만약 특정한 응용 분야만을 대상으로 특수 목적 언어를 설계한다면, 대화의 주제가 한정되기 때문에 심리적 이익을 처음부터 누릴 수 있다. 즉, 통계용 언어에는 복소수 연산 기능이 필요 없고, 문자열 처리 언어에는 복잡한 산술 연산이 필요 없으며, 기계 제어 언어에는 산술보다는 기하학 기능이 더 많을 것이다.

그러나 이렇게 언어의 기능을 제한한 이유가 목적한 분야의 문제들이 일정 정도 이상으로 커지지 않을 것이라는 가정 때문인 경우도 가끔 있다.

특수 목적의 프로그래밍 언어를 사용하는 사람이 신용하지 않는 사람보다 위와 같은 한계를 잘 인식하지 못하는 것은 언어가 사용하는 사람의 사고방식을 좌지우지하기 때문이다. (프로그램과 데이터를 조직화하는 방식 자체를 언어가 결정한다는 뜻)

대부분의 경우, 프로그래머는 자신의 기술 수준이 올라갔을 때 자기 충족적인 만족감을 느끼지만, 특수 목적의 프로그래밍 언어를 사용할 때에는 그와 상관없이 만족감을 느끼게 되기도 한다. 언어에 의해 사고방식이 굳어져서 언어와 자신이 그 언어에 대해 알고 있는 범위 내로 문제를 제한해 파악할 수 있기 때문이다.

어떤 프로그래밍 언어가 그것이 목적한 특수한 일을 잘 처리하면 할수록 그 사용자의 사고는 더욱 더 좁아지는 결과가 된다. 이 모순에서 벗어날 방법은 없어 보인다. (자연 도태에 관한 기본 정리)

그러나 진정한 전문 프로그래머는 하나에 너무 잘 적응한 나머지 오히려 다른 것에는 적응할 수 없게 되는 함정에 빠져 있을 여유가 없다. 문제는 그 함정을 어떻게 피할 수 있느냐다. 아직은 해답을 찾을 길이 요원하지만 계속해서 연구하는 방식으로 찾아내야 한다.

특수 목적 언어는 해당 분야에 적합한 데이터 구조를 제공하고, 그로 인해 좀 더 간결한 프로그램이 가능하며, 사용자의 기존 지식에 잘 부합해야 성공할 가능성이 높다. 특수한 데이터 구조를 제공하면 그 구조와 연관되어 자주 쓰이는 연산기능도 함께 제공하기 마련이다. (그래픽스 쉐이더 코드 언어)

프로그래머가 아닌 사람들을 주된 사용자로 설정한 특수 목적 언어는 사용자의 기존 지식과 유사한 모습을 띠도록 설계된다. 그렇지 않으면 쉽게 적응할 수 없다.

이 과정도 나름의 균형잡기라고 생각된다.

건전한 행동주의적 원칙에 입각하여 설계와 실험을 수행할 수 있는 환경에서 언어를 개발하라.
프로그래밍에만 전문가가 되지 말고 설계에도 전문가가 되어야 한다.

요약

과연 지금은 몇 개 정도의 프로그래밍 언어가 존재할까?

프로그래밍 언어 수가 이렇게 폭발적으로 증가하는 것을 수영장 배수구에 조류가 무수히 자라나는 현상과 동일시해야 할까? 아니면 꼭 필요한 창조적 노력의 건강한 분출로 봐야 할까?

어떤 언어를 간단히 뚝딱 만들어서 책에 싣거나 프로그래머 앞에 던져 놓고 끝낼 수 있는 시절은 지났다.

이론가들은 프로그래밍 언어의 대화적 성격으로 눈을 돌려야 한다. 그래야만 자신들이 연구하는 것은 기호 조작이 아니라 인간 행위임을 깨닫게 될 것이다.

모든 프로그래머는 메타언어 전문가이다.

논의사항

그러나 진정한 전문 프로그래머는 하나에 너무 잘 적응한 나머지 오히려 다른 것에는 적응할 수 없게 되는 함정에 빠져 있을 여유가 없다. 문제는 그 함정을 어떻게 피할 수 있느냐다. 아직은 해답을 찾을 길이 요원하지만 계속해서 연구하는 방식으로 찾아내야 한다.

  • 되게 자주 나오는 상황이라는 생각이 드는데, 전문성을 매우 깊게 가진 프로그래머일수록 다른 것에 실제로 적응하기 힘들다고 보시나요? 그렇다면 그런 길로 빠지는게 부정적으로 보시는 지 그것도 전문성을 가진 영역으로 보시는지 궁금합니다.

13장 그 외의 프로그래밍 도구들

프로그래머가 사용하는 도구에는 프로그래밍 언어만 있는 것이 아니다. 프로그래머는 문서를 읽거나 쓰고 운영체제와 씨름하며 버그를 잡아내는 데 많은 시간을 소비한다. 그런 작업도 사회과학에서 배워 올 만한 부분이 있을 것이다.

그러나 심리학적 관점에서 볼 때 그런 작업들은 프로그래밍 언어보다 항상 무시받아 왔다. 하지만 그런 작업들의 중요성은 언어 못지않다.

프로그램 테스트 도구

프로그램에도 좀 다른 영역이 있다고 생각한다. 버그에 대한 손실이 크게 차이나는 부분이 있는데, 바로 의료와 과학분야와 문화와 예술분야의 차이다. 물론 버그가 발생하지 않는 것이 베스트이지만, 두 영역에서 발생한 버그의 차이는 매우 크게 다르다.

게임에서 발생한 버그와 의료체계에서 발생한 버그의 무게는 많이 다르다.

사실은 자잘한 오류 자체가 존재하지 않는다. 하이픈 한글자 빼먹은 오류마저도 엄청난 재앙을 초래한다. 프로그래밍에서 잘못의 크기와 그로 인해 발생하는 문제 사이에 아무런 연관 관계가 없다. 그것이 프로그래밍의 본질이다.

따라서 프로그램 테스트 작업의 목표를 어떤 공식으로 제시하기란 어렵다. 모든 오류의 제거를 목표로 할 것인가? 그러나 그것은 불가능한 일이다.

분명히, 프로그램 테스트에는 가능한 모든 수단이 동원되어야 한다. 그러나 프로그래밍 도구의 설계자들은 테스트에 대해 별로 관심이 없다.

중요한 것은 테스트 작업은 그 무엇보다 심리학적인 문제다. 신뢰의 문제를 예로 이상적인 테스트 도구란 우리가 프로그램을 신뢰할 수 있을 만큼만 신뢰하도록 도와주는 장치라 할 수 있다. 오류가 있는 프로그램을 합격 처리하거나 오류가 없는 프로그램을 쓸데없이 더 테스트하지 않도록 해줘야 한다는 뜻이다.

어떤 프로그램의 테스트 결과를 신뢰할 수 있으려면 얼마나 많은 코드가 테스트의 대상이 되었는지 알아야 한다. 가장 간단한 방법은 테스트 도구가 그 테스트의 대상이 되었는지 알아야 한다. 가장 간단한 방법은 테스트 도구가 테스트 과정에서 실행되는 코드 영역과 그렇지 않은 영역을 기록해 두었다가 나중에 결과와 함께 출력해 주는 것이다.

인간은 사물을 자신이 보고 싶은 대로 판단하는 경향이 있다. 그러나 우리는 프로그램을 있는 그대로 판단해야 한다. (객관성이 필요, 비자아 프로그래밍) 그러기 위해서는 프로그램 테스트 도구의 도움이 절실하다.

사람들은 자신의 프로그램을 낙관적으로 보고 일단 신뢰하는 경향이 있으므로, 테스트 도구는 그 신뢰를 깨는 데 원칙을 두고 설계되어야 한다.

테스트 결과에 대한 신뢰도를 결정하는 요인에는 그 테스트의 과정 자체만 있는 것이 아니다. 어떤 프로그램을 얼마나 많이 테스트해야 신뢰할 만한 결과를 얻을 수 있는지는 경험에 비추어 판단되기 때문이다.

일관성, 근접성, 간결성이 테스트를 더 쉽게 만들어 준다.

이는 앞서 다룬 객체지향의 영향에 해당된다.

테스트를 빨리 끝내고픈 유혹을 이이기 위해서는 프로그래머가 테스트 분량을 미리 계획하여 명시하도록 시스템 차원에서 강제하는 것도 좋은 방법이다. (분량을 채우지 못하면 보고하거나 자동 실행하여 분량을 파악)

심리학적 측면에서 프로그래머가 테스트 작업을 하는 걸 도울 수 있는 방법이 또 하나 있다. 앞 장에서 근접성을 논할 때 얘기한 대로, 어떤 프로그래머가 오류의 근원을 찾는 데 어려움을 겪고 있다면 잘못된 코드 영역을 살피고 있기 때문인 경우가 많다.

프로그래머가 일단 한 장소에 갇히면 다른 장소로 눈을 돌리게 만들기가 굉장히 어렵다. 따라서 디버깅을 못해 고생하고 있는 동료에게 줄 수 있는 가장 좋은 도움은 그가 다른 곳을 보게 만드는 것이다.

핵심은 프로그래머가 한 영역에 집착하지 않도록 하는 것이다.

운영체제

프로그래밍 언어 설계에서 끝없는 논쟁거리 중 하나는 디버깅 도구가 어디에 위치해 있어야 좋은가 하는 문제다.

디버깅 도구가 언어의 일부여야 할까, 아니면 운영체제에 포함되어야 할까? 지금 여기서 특정한 방향으로 결론을 내려고 이 얘기를 꺼낸 것은 아닌 양쪽 모두의 충분한 이유가 있다.

언어에 디버깅 도구가 포함되어야 한다는 사람들은 프로그래머가 단지 디버깅만을 위해 새로운 언어를 배워야 하는 건 불합리하다라고 말하지만 언어를 통해 디버깅을 하면 프로그래머와 실제 운영체제 사이에 언어라는 계층이 위치함으로써 운영체제의 여러 실질적인 측면을 프로그래머가 보지 못할 수 있다.

프로그래머들은 운영 환경이 어떻든 간에 결국에는 자신에게 유리한 방향으로 적응하게 된다. 운영 환경이 나쁘든 상관이 없다. 한 명이 어떤 행동을 하여 전체 운영에는 해를 끼쳤지만 자신은 이득을 봤다면 다른 프로그래머들도 그 행동을 따라할 것이다.

작업 입력 방식은 결국 프로그래머와 컴퓨터 사이에 또 다른 사람이 위치하는 기존 방식과 흡사한 형태가 되었고, 자신의 작업에 대한 회송시간을 줄이려면 운영체제가 아닌 사람을 상대해야 한다는 사실은 변하지 않았다.

시스템이 효과적이고 능률적으로 사용되도록 확실히 보장하려면, 효과적이고 능률적인 사용법을 가장 쉬운 사용법으로 만드는 게 최선이다. 설계가 잘된 운영체제라면 가장 많이 사용되는 또는 그래야 할 작업제어 루틴 목록을 사용자에게 제공할 수 있을 것이다. 그렇다면 프로그래머들은 자연히 시스템을 잘 사용하게 된다.

시분할 대 배치

  • 시분할 시스템은 컴퓨터 응답 시간을 최소화하기 위한 시스템으로, 다중 사용자를 지원합니다. 배치 처리 시스템은 여러 프로그램을 순차적으로 실행합니다.
  • 배치 처리는 컴퓨터로 계산할 때 큰 이점이 있습니다. 이미지 1장당 처리 시간을 대폭 줄여주며, 커다란 신경망에서는 데이터 전송이 병목이 되는 경우가 자주 있습니다. 배치 처리를 함으로써 버스에 주는 부하를 줄입니다.

문서화

문서화는 프로그래밍에서 피마자유와 같은 존재다.

피마자유는 아주까리 씨에서 추출한 기름으로 독특한 냄새가 나지만, 피부진정등에 효과등을 지닌 특징이 있다. (과거에는 질병을 고치는 효능이 있다고 믿음)

관리자는 문서화가 프로그래머에게 유용한 작업이라고 생각하지만, 프로그래머는 문서화를 싫어한다. 문서화는 잘할 때에만 가치가 있지, 그렇지 않다면 한 하느니만 못하다.

프로그래머가 좋은 문서를 만들도록 강제할 방법은 없다. 잘하는 척 하면서 쓸모없는 문서를 만드는 방법은 너무나 다양하기 때문에 강제로 시켜봤자 안 좋은 문서를 쏟아낼 뿐이다. 따라서 유일한 희망은 문서를 잘 만들면 자신에게도 이득이 된다고 프로그래머를 납득시키는 방법뿐이다.

프로그래머가 문서화를 쓸모없다고 생각한다면, 문서화는 작업량을 최소화하는 방향으로 진행될 것이다. 그러나 문서화 작업이 가시적인 효과를 거둔다면, 모든 프로그래머가 어느 정도 좋은 문서를 만들려 할 것이다.

따라서 문서화의 이점을 프로그래머들이 체감할 수 있는 환경을 조성해야 한다.

우리는 문서화에 너무 많은 부분을 기대하는 잘못을 범하곤 한다.

첫째, 사람마다 프로그램의 문서를 읽는 목적이 전부 다르므로 모두 동일한 수준으로 만족시키는 문서 체계는 존재하지 않는다. 따라서 우리는 어느정도 적당한 목적을 하나 세우고 그에 부합할 만큼만 좋은 문서를 만드는 노력을 해야 한다.

둘째, 아무리 문서화를 잘해도 불가능한 것들이 있다. 예를 들어, 어떤 프로그램을 스물다섯 단어만 사용해서 비전문가에게 이해시키기는 불가능하다.

어떤 프로그램에 대한 문서를 활용하려면 반드시 노력과 사전 지식이 어느정도 필요하다. 영어를 못하는 사람은 영어를 읽지 못한다. (프로그래밍 협업자 끼리의 문서화와 팀내 영역에 대한 문서화는 다르다.)

깊이는 문서화에서 중요한 개념 중 하나다. 시스템이 클수록 더욱 그러하다. 일정 규모 이상의 시스템에서는 문서를 읽는 사람마다 얻으려 하는 정보의 상세 수준이 다르다. 깊이가 가장 얕은 문서라도 읽는 사람이 그것을 읽을 수 있는지 여부를 판단할 만큼 충분히 상세해야 한다.

문서화라 해서 마치 책처럼 물리적으로 존재하는 문서만 생각하는 것은 근시안적인 사고다. 아마도 프로그래밍 문서화 문제는 프로그램들을 그것이 실행되는, 바로 그 컴퓨터를 이용해 문서화하기 시작하기 전까지 정말로 해결됐다고 할 수 없을 것이다. (지금은 매우 자동화되어 있다.)

책이라는 매체에 분명한 한계가 있고, 그정도로 유연한 매체가 아닐 뿐더라 속도를 따라잡지 못한다. 또한 시스템이 복잡해지는 것에 따라 좀 더 능동적인 안내자가 필요하다.

이런 모든 과정에는 비용이 든다.

흐름도 추출기, 의존성 View와 같은 것을 문서화로 볼 수 있을까? 이는 디버깅 도구 쯤으로 생각할 수 있다.

책에서 말하는 가장 좋은 형태는 모든 질문과 답변을 단일 저장소에 모아서 원하는 정보를 쉽게 찾아볼 수 있는 환경을 제공하는 것이라 말한다. 문서의 내용을 항상 최신으로 유지시키는 장치만 갖춘다면 이 방식은 프로그래머가 곧 문서이던 시절로 우리를 돌려놓아 줄 것이다. 회사나 시스템 규모가 작을 때에는 명시적인 문서화에 그렇게 신경 쓸 필요가 없다.

어떤 프로그래머든 자신이 알고 있는 걸 모두 문서에 다 써 넣을 수는 없으며, 설령 그럴 수 있다 해도 모든 사용자가 자신이 원하는 정보를 문서에서 스스로 찾아낼 수는 없다. 이 방식에서 문제가 발생하는 경우는 프로그래머가 회사를 떠날 때인데, 비자아적 프로그래밍이 실천되고 있다면 크게 문제될 것은 없다.

문서화에 대해 프로그래밍 심리학적으로 논해야 할 사항은 프로그래머들이 문서화를 누구나 잘할 수 있는 작업 혹은 프로그래머가 될 정도로 똑똑하지는 않은 사람이 하는 업무라고 착각하고 있다는 사실 정도가 유일하다.

요약

시스템은 복잡하다. 컴퓨터 시스템은 단지 하드웨어뿐인 것도 아니고, 소프트웨어뿐인 것도 아니며, 심지어 인간 + 하드웨어 + 소프트웨어인 것도 아니다. 시스템과 함께 발달한 공식/비공식적인 절차도 시스템의 일부다.

논의사항

문서화는 잘할 때에만 가치가 있지, 그렇지 않다면 한 하느니만 못하다.

  • 문서화를 차라리 안하는 게 좋았던 상황에 대해서 경험 해보신 상황이 있었을까요?

5부 에필로그

어떤 책이든 독파했다면 배움이라는 형태로 이미 상을 받았을 것이다.
“인간을 만드는 일은 평생이 걸리는 작업이다.”

이 책은 심리학이라는 관점에서 프로그래밍을 다뤘지만, 프로그래밍의 영역이 매우 넓은 분야라 그런지 다양한 측면에서 이야기를 들을 수 있었다. 계속해서 노력해야 하는 점과 과거와의 차이점 그리고 바뀌지 않았던 부분까지 스스로 생각할 수 있는 여지를 많이 준 책이라고 생각한다.

한번 읽고 끝내는 것이 아닌 지속해서 읽어야 할 것 같은 책이다.

댓글남기기