본문 바로가기
Homo Coding

프로그래밍은 여러분의 팀을 가르치기도 한다.

by javauser 2009. 9. 23.


프로그래밍은 어떤 문화와 상호작용하는 부분으로 발생되는 어떤 것이라 생각할 수 있다. - 어떤 문화는 두가지 서로 다른 대상이 있다. 하나의 "대상"은 CPU이며, 다른 대상은 다른 프로그래머들로 구성된다. 그리고 그러한 다른 프로그래머들은 일반적으로 무시되거나, 최소한 잘못 취급되는 사람들이다.

프로그래밍은 두가지 목표를 가진다.

한가지 목표는 물론 어떤 것을 수행하는 것이다. 채무 테이블을 계산하고, 변경된 부분에 대한 목록을 보여주고, Ebay에서 어떤 사람을 탐지하거나, 혹은 인간 플레이어의 군대를 무찌르는 것이다. 이러한 목표는 계산하는 환경에 초점을 맞춘 것이다.

또 다른 목표는 프로그래머들 간의 지식을 전달하는 것이다. 이는 많은 장점을 가진다. 주어진 부분의 코드를 이해하는 사람의 수를 증기사키고, 새로운 일을 수행하는 개발자에게 자유를 주며 (그가 더 이상 주어진 프로그램이나 프로세스를 유지할 수 있는 유일한 사람이 아니라는 것이다.), 종종 더 나은 수행을 하게끔 한다. - 당신의 코드를 데나에게 보여주는 행위는 그녀가 당신의 코드를 향상시킬 수 있는 지점을 지적하는 기회를 가지게끔 한다. 물론, 이는 두가지 양날을 가진 칼과 같을 수 있으며, 이는 데나가 자신이 작성한 코드에 영향을 미치는 편향을 가지고 있기 때문이다. (따라서 여러분이 배울 수 있는 것이다.)

대상으로써의 CPU
CPU는 관대하지 않은 대상이지만, 고정된 개체로의 바로 그 성질로 인해 상쇄될 수 있는 혹은 어떤 경우에 있어서 활용될 수 있는 잘 알려진 특징을 지닌다.

사용하고 있는 프로그래밍 언어는 그 자체로 고유한 고정된 규칙을 가진다. 예를 들어 C에서 일반적인 프로그램에 대한 "시작 지점"은 "int main(int, char**)의 시그너처를 가진 함수이다. 물론, 환경에 따라 "int _main(int, char**)"와 같이 작성할 수도 있으며, 다른 환경에서는 main()을 전혀 사용할 수도 없을 것이다. 즉, 적절한 경우 라이브러리가 제공하는 main() 호출을 하는 이벤트 핸들러를 작성할 수도 있다.

하지만, 관점은 단순하다. 즉, 규칙이 있으며, 예외가 존재하면 주어진 프로그램의 대상 코드가 발생되는 것을 정확하게 결정하는 유효한 결정 트리를 쉽게 구성할 수 있다. 에러는 실제 발생하고 있는 것에 적합하도록 결정 트리를 수정함으로써 해결될 수 있다. (예를 들어, 에러의 수정)

이는 매우 중요하다. 예를 들어, 항공 시뮬레이터 코드는 모든 구문의 결과를 증명해서 검증되어야 한다. 만일 CPU가 엄격하게 결정하지 않는다면, 이는 불가능할 것이며 파일럿은 모든 비행의 모든 순간을 정말로 심혈을 기울여야 될 것이다.

C와 같은 고수준 언어 (그리고 "어셈블러"라고 하지 않는 모든 다른 언어)는 결정적인 성질을 보존함으로써 프로그래머로부터 실제 CPU를 추상화하도록 설계되었으며, 시간이 흐름에 따라 이러한 추상화는 규모 면에서 증가하고 있다.

가상 머신은 just-in-time 컴파일을 제공함으로써 이러한 규칙을 다소 다른 형태로 사용한다. 예를 들어, Sun의 VM은 주어진 클래스에서 가장 공통적인 실행 경로를 검사해서 해당 경로의 결과 머신 코드를 최적화시킨다. 만일 공통 경로가 실행시에 추후에 바뀐다면, VM은 가능한 한 가장 효율적인 방법으로 실행하는 바이트코드를 재컴파일 한다.

적응성이 있는 just-in-time 컴파일은 여러분이 작성한 것은 반드시 샐행되는 것일 필요가 없다는 것을 의미한다. 실행 동안 VM에서 발생되는 것을 정확하게 예측하는 것이 가능한 반면에 상태 변이에 대한 수는 엄청나며 왠만한 인내심으로 검증할 것은 아니다.

적응성의 JIT는 또한 효율적인 실시간 코드를 만들어내는데 여러분이 작성할 수 있는 코드의 종류에 영향을 미친다. 이 부분은 매우 중요하다.

대상으로써의 프로그래머
코딩 팀의 다른 멤러는 여러분의 코드에 대한 다른 독자들이다. CPU가 하는 것처럼 대상 코드를 읽는 대신에, 이들은 소스를 읽으며, 여러분이 해당 소스를 어떻게 작성하는지가 상당히 중요하다. 왜냐하면 컴파일러가 좋은 대상 코드를 생성할 수 있는 방식으로 작성해야할 뿐만 아니라, 사람(여러분을 포함해서)이 이를 읽을 수 있는 형태로 작성해야 하기 때문이다.

사람들이 코드를 어떻게 이해하는지를 이해하려면 사람들이 어떻게 이해하는지를 알 필요가 있다.

사람들이 학습하는 방법
사람들은 느리게 학습하게 된다. 이는 이들이 우둔하다는 의미는 아니다. 단지 이들이 사람이라는 의미이다.

1950년에 작성된 논문인 "마법의 수 7 ± 2 (The Magical Number Seven, Plus or Minus Two)"는 어떻게 사람이 학습하는지가 나타나있다. 여기에는 빈약하게 정리되어 있으며, 관심이 있다면 더 많은 것을 배우기 위해 원문을 읽는 것을 권한다.

기본적으로 사람은 정보의 덩어리를 통합함으로써 학습한다. 덩어리는 정보의 단위이며, 이는 뉴런이 사람의 뇌에서 어떻게 작동하는지를 반영하는 것으로 볼 수 있다.

사람들은 일반적으로 한번에 7가지 덩어리를 통합할 수 있으며, 다양한 환경에 따라 두가지가 더해지거나 빼질 수 있다.

어떤 사람이 이미 자신이 이해하고 있는 덩어리를 가지고 정보의 결과가 응집되는 형태로 새로운 정보 덩어리를 덧붙일 때에 학습이 발생된다. 따라서, 위의 "대상으로써의 CPU" 처음에 단순하고 보편적으로 이해되는 정보로 시작을 했고("CPU는 예상 가능하다", "C 프로그램은 이와 같은 함수로 시작한다"), 예외와 다른 방법을 추가하기 위해 이를 정제한다. 어떤 이에게는 C의 시작 시점에 대한 구절의 "덩어리 수"는 대략 4가지 덩어리로 구성된다. - 낮은 덩어리 셈 덕분에 대부분의 프로그래머들은 쉽게 통합한다.

만일 독자가 C가 무엇인지 모른다거나, C 함수 선언이 무엇을 의미하고 어떻게 생겼는지 알지 못한다면, 이들은 통합할 새로운 덩어리가 되며, 이는 학습하는데 걸림돌이 될 것이다.

C++에 대한 적응
덩어리를 만드는 또 다른 예제는 C++에 대한 적응에서 살펴볼 수 있다. C와 유사한 덕분에 - 대부분의 프로그래머들이 그 당시 사용했던 - 쉽게 적응되었다. 기능이 늘어나고, 네임스페이스, 템플릿, 등 다른 변화들이 추가되면서, 이제는 적응 속도가 느려졌으며 이는 이전 보다도 C++를 더 이해할 것이 더 많아졌기 때문일 뿐만 아니라, 이전 보다도 새로운 덩어리에 대한 더 많은 통합을 필요로 하는 "보통의" 언어 C와 다르기 때문이기도 하다.

더 어려워진 것이다. 더 많은 것이 추가되었고 이전보다 더 달라졌기 때문이다.

한가지 사실 : 사람들은 정말로 배우기 원하지 않는다
이는 어렵게 느껴지는 것이다. 즉, 일반적으로 사람들은 그리 많은 것을 배우기 정말로 원하지 않는다는 것을 인식해야 한다. 프로그래머로서 우리는 어떠한 것을 배우는 것을 즐기는 경향이 있지만, 일반적으로 사람들은 정지 신호가 더 이상 빨간색이 아니라 이제 점등되는 흰색이라는 것을 배우기 원하지 않는다. 익숙하지 않기 때문에 어떤 사실이 이전과 동일하다는 방식으로 이해하기를 원한다. 학습하는 것에 대해 통제하기를 원한다.

우리들의 경험은 통합하기 위한 덩어리가 되며, 학습은 덩어리의 통합된 형태가 응집된 단위로 되는 것이기 때문에 새로운 정보는 이전 정보와 충돌하게 된다. - 이는 종종 불편한 것이다. 물론, 경험은 새로운 정보를 통합하는데 도움이 될 수 있다 - 따라서 (그렇게 많이 익숙했던 8각형의 적색 신호 대신에) 점멸되는 흰색의 정지 신호를 보는 다섯번째에 이러한 상황에 더 익숙해지며 이를 정지 신호로 보기 시작하며 이제 이상한 것이 아니라는 것을 인식한다.

사람들이 알 필요가 있는 것과 이미 알고 있는 것 사이의 차이가 클수록, 새로운 정보를 통합하기가 더 어려워지는 것을 인식하는 것이 중요하다고 한다. 만일 실행코드에 대한 anonymous 블럭에 익숙하지 않은 사람 앞에서 closure를 사용한다면, 이들이 인터페이스의 anonymous 구현체를 선호한다고 말하는 것에 준비를 해야하며, 명명된 메소드가 좋다. 이것이 이들이 알고 있는 것이다. 이들은 그러한 문법에 익숙하다. 즉, 안전하다.

"Hello, World" 가 프로그래머에게 왜 그렇게 중요한지가 바로 이것이다. 코더에게 분명히 제한적인 것에 초점을 맞추게 한다. 대부분의 프로그래머들은 편집/컴파일/실행 주기(Maven 덕택으로 종종 "디버그" 단계 혹은 "테스트" 단계를 가진다.)를 빨리 이해하며 "Hello, World"는 언어가 공통 업무를 어떻게 구현하는지에만 초점을 맞추게 한다.

다음과 같은 것에 대해 생각해보자. 여러분은 "Hello, World"가 무엇을 하는지를 안다. "Hello, World"를 화면에 보여준다. 단순하고 직관적이다. 따라서, 프로그램에서 텍스트를 찾아보고, 그 외의 것은 프로그래밍 언어 구조이다. 이는 찾아야할 진입점과, 출력 텍스트에 대한 메커니즘, 캡슐화되는 부분에 대한 분량을 제공한다. (언어가 그러한 것들을 가진다고 가정하고 이를 실현해보자. 여러분이 지금 작업하고 있는 언어는 그와 같은 성질을 가진다.)

이는 또한 프로그래머들에게 어떤 것을 진정으로 단순하게 수행하기 위해 자신들이 얼마나 많은 작업을 실제로 수행해야 하는지를 판단하는 수단을 제공한다. 초기 프로그래밍 메뉴얼이 권고하는 "Hello, World"의 Window/C 버전은 엄청났었다. 단순한 콘솔에 표현하는 C에서 4줄 가량인데, Window API에서 거의 70줄 정도 된다. 이는 프로그래머들에게 단순한 작업이 필요로 하는 노력이 어떤 종류인지에 대한 생각(더 나은 방식이든 더 안좋은 방식이든)을 제공한다. - 그렇다 하더라도 Windows 경우처럼 단순한 메시지가 실제로 수많은 할일을 가진다. (공평하게 말하자면, 모든 GUI "Hello World"는 이와 같은 문제를 가진다.)

그래서 사람들이 여러분의 장점을 학습하는 방법을 어떻게 사용할 것인가?
여러분이 다른 사람들이 빨리 무엇인가를 습득하는데 도우려고 할 때 몇가지 염두해두어야 하는 것이 있다.

첫번째 알고 있는 지점에서 시작한다 - 즉, 다른 사람에게 알려진 것을 의미한다. 이는 다른 사람이 알고 있는 것을 학습하고 이들이 사용하는 용어를 학습하는 것과 관련된다. 공통된 패턴을 사용할 수도 있겠지만, 여러분이 하던 것과 전혀 다른 것으로 부를 수도 있다. 따라서, 그들이 알고 있는 용어를 사용하거나 대화에서 사용가능한 용어를 도입함으로써 공통적인 입지를 만들 필요가 있다.

두번째, 변화를 서서히 도입하라. 이는 예를 들면, DI(dependency injection)이나 AOP(aspect-oriented programming)을 깊이 파헤치기 전에 구체적인 클래스 대신 인터페이스를 사용하는 소개를 하는 것과 같이 단순할 필요가 있다. 작은 변화를 통해 "따라 잡을 수" 있는 기회를 이들에게 제공한다. - 이들에게 작고 소화가 쉬운 덩어리를 보여주는 것을 통합하는 것

세번째, idiom을 보여준다. 만일 여러분이 사용하고 있는 언어나 접근방법이 한번에 이해되지 못하는 관용적인 절차를 가지고 있다면 (즉, 대부분의 closure를 아는 사람들이 closure가 익숙하지 않은 사람들에게 전혀 idom이 되지 않는 것) 듣는 이들에게 "전문가"가 하는 것을 보여줄 기회를 가지게 할 필요가 있다. - 왜냐하면 이러한 것들이 여러분에게 아무리 간단하더라도 이들은 그들 자신만의 idom에 도달하지 못하기 때문이다.

이전 관점과 관련해서 될 수 있는 한 청중(대상)과 가까이 머무려고 노력하라. idiom은 좋지만, 여러분이 대화하고 있는 사람이 여러분이 보여주고 있는 것과 관련된 접근 방식을 가지지 못한다면 이를 유지시키는 어떠한 것도 이들이게 줄 수 있는 방법이 없다. Schwartzian Transform을 생각해보자. set으로부터 map을 만들며, key는 정렬 필드이고, 그 값은 정렬된 요소이며, 정렬은 key를 기반으로 이루어진다. 그 다음에 (정렬된) 키의 순서대로 set을 만든다. 이는 적절하게 정렬될 수 있는 key를 생성하는 기능을 사용하는데, 이것이 closure가 될 수 있다.

만일 여러분의 대상(청중)들이 map을 잘 이해하지 못하거나, 대상(청중)이 어떠한 방식(ASM, FORTH, COBOL, 혹은 자바?)으로 사고하는 것에 고착되어 있다면, Schwartzian Tranform은 검은 마법과 같이 보일 수 있다. 자바 프로그래머들은 더 나은 기회를 가지고 있지만, 정렬 키를 생성하는데 사용하는 메커니즘 때문에 이는 매우 이상하게 보일 수 있다. 자바에서 이는 관용적이지 않다. 따라서 대상(청중)을 위해 통합에 대한 어려움을 최소화시키는 조그마한 단계로 Schwartzian Transform을 접근하도록 한다.

결론

프로그래밍은 CPU에게 무엇을 하라고 말하는 것일 뿐만 아니라, 여러분 동료들에게 여러분이 어떻게 작업하는지를 가르치는 것이며, 이를 통해 어떻게 코드가 동작하는지를 배우는 것이다. 훌륭한 프로그램과 효율적인 프로그래머들을 만들어내는 것이 협업 노력(collaborative effort)이지만, 혼란스러운 사용자 인터페이스와 의기소침한 코드를 만들어내는 것 역시 협업 노력이 된다.

차이는 코딩을 수행하는 팀이 CPU나 자신 팀에 대해서만 코딩을 하는 시간을 갖는 것이 아니라, CPU와 팀 모두에게 시간을 갖는 것이다.

CPU는 판단을 적게 하고 더 예측이 가능한 이유로 통상 작성하기 더 쉽지만, CPU 역시 결코 좋은 대상이 되지 못한다. 제조에서 발생되는 고정된 몇가지 능력을 가진다. 항상 동일한 방식으로 행동하게 된다.

그렇지만, 같이 일하고 팀의 이익을 위해 작성하는 일반 대중, 경험이 없는 코더들로 구성된 팀은 최상의 팀이 되는 능력을 가지며, 이들은 다른 최상의 팀을 만드는 학습 접근법을 받아들일 수 있다.

팀이 자신의 작업을 단순하게 코드를 작성하는 것으로 볼 것인지 아니면 코드와 학습 모두의 목표와 부합하는 작업을 볼 것인지로 결국 귀결된다.


원문 : http://www.theserverside.com/tt/articles/article.tss?track=NL-461&ad=725623&l=ProgrammingisAlsoTeachingYourTeam&asrc=EM_NLN_9286305&uid=2487673

반응형