대표 번역가 : 백재영


실리콘밸리를 꿈꾸는 개발자.
현재 LF 플랫폼 개발팀에서 있으며 요즘은 번역의 어려움과 재미를 한창 느끼는 중이다. 


원문 링크





스프링 빈이 진짜 뭘까?


오늘 Spring Boot Application 내부에서 무슨 일이 벌어지고 있는지 이해하려고 하는 중 멘붕이 왔다.


스프링을 처음 접하면서 꽤 많은 시간을 구글링과 문서 읽기에 쏟아부었지만 ‘빈'과 같은 기본적인 개념에 관해서는 사전지식을 전제로 한다고 알고 있었다.


Pivotal의 스프링 팀에 있는 내 친구이자 동료인 Mark Fisher가 내게 찾아와 설명해주는 대신 나는 이것에 대해 글을 쓰기로 약속했다.


그 결과는 지금 보고 있는 이 블로그와 여기에 있다. https://github.com/markfisher/spring-boot-hello-world


태초에 XML이 있었다

스프링은 자바 애플리케이션이 종속된 메인 클래스를 구성하는 데에 J2EE보다 더 간단한 XML 기반의 방식을 제공한다.


단순히 모든 것을 자바의 new를 이용하여 인스턴스화하는 것은 이상적인 것이 아니었다. 이는 모든 종속성을 코드에 기술해야하므로 로컬 테스트를 위한 데이터베이스와 CI 또는 프로덕션을 위한 다른 데이터베이스를 쉽게 사용할 수 없었기 때문이다.


데이터베이스 커넥션같은 것들을 추상화한 자신만의 팩토리를 만드는 대신, 스프링은 이 모든 것들을 XML 하나로 제공한다.


스프링은 구동시 환경에 특정한 XML을 읽어들이고 XML에 있는 것들을 기반으로 해당 클래스의 인스턴스를 생성한다.

 

그리고 이런 인스턴스들은... 이런 식의 (beans)이다.

 

ApplicationContext.getBean()

 

지금은 @Annotation이다

세월이 흘러 XML은 @Configuration @ConfigurationProperties 같은 주석이 달린 자바 코드로 대체되었다.

 

Screen Shot 2017-10-11 at 10.11.48 PM.png


팩토리 메소드에 @Bean이 달린 것에 주목하라.


설정 클래스가 META-INF/spring.factories에 포함되어 있으면, 스프링 부트 애플리케이션은 시작시 자동으로 팩토리 메소드를 호출하여 해당 클래스의 싱글턴 인스턴스를 생성한다.


이건 마법이다

그리고 이런 인스턴스는 여전히 이라 불린다


Spring Initializr와 모든 starter들은 다 뭐냐고?

이제 configuration scanning이 뭔지 알았으니 스프링 부트 스타터의 역할은 더 이해하기 쉬울 것이다.


스프링 부트 애플리케이션의 종속성에 스타터를 포함시킴으로써 스프링은 스타터 내부의 설정 클래스를 검색하여 해당 스타터에 대한 을 자동으로 생성하게 된다.

 

Initializr injection

짠!



저작자 표시 비영리 동일 조건 변경 허락
신고

설정

트랙백

댓글








대표 번역가 : 백재영


실리콘밸리를 꿈꾸는 개발자.
현재 LF 플랫폼 개발팀에서 있으며 요즘은 번역의 어려움과 재미를 한창 느끼는 중이다. 


원문 링크





나는 2년 전에 엔지니어링 관리자가 되었다. 관리자로 있는 동안 주된 과제 중 하나는 우리 팀에 대한 나의 리더십과 코딩을 하고 싶은 욕구 사이의 균형을 잡는 것이었다.


분명 이런 일로 고군분투 하는 것은 나만은 아닐 것이라 생각한다. 그래서 내 생각을 공유하고자 한다.



왜 엔지니어링 관리자가 기술적으로 뛰어나야 하는가


나는 실무 위주의 기술적으로 뛰어난 관리자가 엔지니어링 팀(그리고 대부분의 시간에 딜버트의 법칙을 벗어난 팀)의 최고의 리더라고 생각한다. 기술적으로 뛰어난 관리자로서 당신은,

  • 팀원들이 수행해야 할 직무에 관련된 숨겨진 복잡성을 이해하고 팀원들과 더 쉽게 의사소통할 수 있으며 제품 또는 마케팅 같은 비 기술적인 관계자들의 메시지를 단순화 할 수 있을 것이다.

  • 팀원들을 효율적으로 이끌고 기술영역에서 솔선수범할 수 있을 것이다.

  • 팀이 쓸 수 있는 툴과 프레임워크를 숙지하고 더 나은 기술적 방향을 제시할 수 있을 것이다.

  • 팀원들의 신뢰와 존경을 더욱 받기 쉬워질 것이다. 이것은 비기술적 관리자들은 그럴 수 없다는 뜻은 아니다.

  • 향후 컨트리뷰터로 돌아갈 수 있도록 여지를 두어라.


기술력을 갈고 닦는 것은 정말 좋은 생각이라는 것에 다들 동의할 것이다. 그러나 이것들은 도전이 없이는 불가능하다.




코더 vs 멘토


당신이 직면하게 될 첫 번째 도전은 엔지니어로서 그리고 멘토로서의 갈등이다. 엔지니어로서는 팀이 직면한 모든 흥미로운 기술적 도전들을 해결하려 할 것이다. 반면, 멘토로서는 능력을 향상시키고 더 나은 개발자가 되고자 하는 팀원에게 (도움이 되는) 문제를 주고 싶어 할 것이다.


시니어 개발자가 부족하고 주니어 개발자가 많은 팀에서는 이 문제가 심각해질 수 있다. 그럴 경우, 엔지니어링 관리자는 자신의 역할에서 멘토십을 더욱 강조해야 한다.


당신의 팀을 성공적으로 만들어라

어떤 코딩보다도 팀과 팀원들이 우선이다. 당신이 코딩하는 데에 전념할 수 있는 필요조건은 팀이 성공했을 때이다.


관리자로서 당신은 제품을 만드는 것이 아니라, 제품을 만들 수 있는 팀을 꾸리는 것이다. 따라서 팀을 성공적으로 운영하는 것이 자신을 평가할 수 있는 주 목표 및 척도가 되어야 한다. 만약 당신이 행복한 엔지니어들로 구성된 성공적인 팀을 이끈다면 팀의 성공은 따라올 것이고, 팀원과 상사에게 성과를 설명하려는 일에 시간을 덜 보낼 수 있을 것이다.

의사 결정에 병목 현상이 없는 능력을 갖춘 실력있는 팀원들로 이루어진 자립심 있는 팀은 당신이 뭔가 다른 일을 할 수 있도록 해줄 것이다.



당신의 말에는 더 많은 무게가 있다


나에게 또다른 도전은 팀이 기술 문제를 해결하는 방법을 논의할 때 너무 강하게 내 의견을 표현하는 것이었다. 전 팀원과의 feedback session에서 팀원이 알려주기 전까지는 이 문제에 대해 알지 못했다. 그녀는 “우리가 기술 토론을 할 때 당신은 너무 독단적이에요… 팀원들에게 더 양보해야 해요.”라는 식으로 말했다.


일부 관리자는 정말 강경하고 권위있게 말을 하지만, 그것은 다른 이들이 가질 수 있는 의견차를 표현하지 못하게 방해할 수 있고 이는 좋지 못한 해결책으로 귀결될 수 있다는 것을 깨달았다.


그래서 내 조언은?



답을 하기보다는 항상 마지막으로 이야기하고 질문해라

이것은 아무리 강조해도 지나치지 않다. 관리자는 자신의 글이나 말하는 모든 단어가 어떤 식으로든 팀원의 아이디어나 제안을 잠재적으로 침묵시킬 수 있다는 것을 충분히 인지해야 한다.


더 나아가 James Everingham은 양자 역학 비유에서 관리자의 단지 관찰만으로도 프로젝트의 결과를 바꿀 수 있다고 이야기한다.


관찰자 효과는 직장에서 실제로 발생하며, 프로젝트의 관리자가 되는 것만으로도 프로젝트 결과에 영향을 끼칠 수 있다. 종종 관리자는 팀원들을 불러 칠판에 적기 시작하면서 “우리가 해야 할 것들” 또는 “내가 생각한 것들” 또는 “이것에 대해 생각해볼 수 있는 한 방법은...” 이라고 말할 것이다. 그들은 가치를 높이려 노력한다. 또한 우리도 항상 가치를 높이길 원한다. 그러나 여러분이 권위자의 자리에 있고 이런 식으로 한다면 당신은 제한된 결과를 초래한 것이며 성공의 길을 크게 제한한 것이다.



개발자 vs 관리자


내가 직면한 더 큰 도전은 개발자의 시간표와 관리자의 시간표를 조합하는 것이었다. Paul Graham의 말에 따르면,

대부분의 영향력 있는 사람들은 관리자의 시간표에 있다. 이건 지시의 시간표이다. 그러나 프로그래머나 작가같이 뭔가를 만드는 사람들에게는 시간을 사용하는 또다른 방법이 있다. 그들은 보통 적어도 반나절 단위로 시간을 사용하는 걸 선호한다. 글이나 프로그램을 한시간 단위로 쓸 수는 없다. 1시간은 간신히 시작할 시간이다.


간단히 말해서, 관리자의 단편적이고 수동적인 회의 중심의 일정은 코딩에 필요한 집중 요구 사항(일종의 Deep Work 같은)을 잘 나타내지 않는다. 관리자와 엔지니어의 일정은 서로 반대된다고 말할 수 있다. 엔지니어는 가능한 주의가 산만하지 않아야 하는 반면, 미팅에 참석하지 않거나 다른 팀과 소통하지 않는 관리자는 조직에서 충분히 눈에 띄지 않는다는 평을 받을 수 있다.


두 일정을 섞지 마라


http://dilbert.com/strip/2012-05-30



시도조차 하지 마라. 이건 좌절을 느끼게 해주고 비생산적인 방법이다. 물과 기름처럼, 이것들을 분리하고 독립시켜서 본연의 상태 그대로 유지하는 것이 가장 좋다.


나는 점심시간과 같은 자연스런 방해와 내 일정을 분리하려 노력한다. 오전 내내 회의를 계속하고, 지친 상태에서 엔지니어로 돌아와 오후를 보내며 어려운 프로그래밍 문제에 집중하려고 한다. 적어도 일주일에 두 번은 그렇게 하려고 노력한다.

나는 충분한 점심시간을 갖고 가급적이면 사무실 밖에서 산책하면 회의에 있었던 신경을 끊고 다시 돌아와 상쾌한 마음으로 생산적으로 코딩을 할 수 있다는 것을 알게 되었다.


엔지니어일 때는 가능한 집중을 방해하는 모든 것들을 피해야 한다. 우선 이메일을 꺼라. 그리고 브라우저에서 주의를 산만케 하는 모든 탭ㅡ가령 Facebookㅡ을 닫거나 새 브라우저를 열어 찾으려 하는 문서만 참조해라. 끝으로, HipChat/Slack도 꺼라. 물론 긴급 이슈가 생겼을 때 팀원이 당신을 찾을 수 있도록 몇몇의 커뮤니케이션 채널은 항상 열어 놓아야 한다.


생산적이고 집중력을 발휘할 수 있다는 것은 당신의 육체 그리고 정신에 크게 의존한다. 주위 환경을 바꾸거나 조정함으로써(다른 책상/장소에서 일하거나, 특정 유형의 음악을 듣거나 무엇이든 간에), 정신을 최대한 생산적으로 만들 수 있다.


Cal Newport의 책 Deep Work에서 심도깊은 작업을 처리하는 법에 대해 더 많은 요령을 얻을 수 있다.



코드 병목 현상


바쁜 일정을 감안할 때, 아마도 빠른 시일 내에 코딩을 마치기 힘들 것이고, 따라서 아마 일부 기능은 프로덕션에 병합되거나 배포되기 힘들 것이다. 더 나쁜 것은,  뭔가 잘못되기라도 한다면, 운영중인 사이트의 이슈나 파이프라인이 깨졌을 때와 같은 기술적 문제를 급하게 처리하지 못할 수도 있다.


팀의 리더로서 당신은 팀원들이 회의나 대화에 방해받지 않고 코딩에 집중할 수 있도록 분주히 움직여야 한다. 다시 말해서, 당신의 일은 코딩하는 것이 아니라 팀원들이 효율적으로 코딩할 수 있도록 하고 팀원의 성과를 부각시키는 것이다.


코드를 꼭 출시할 필요는 없다??

한 친구와 프로덕션 코드에 직접 참여하고 관여하는 매니저들에 관해 이야기 나눌  때 이런 조언을 해줬다.

팀의 병목이 되어선 안된다. 당신의 도움 없이 모든 기술적인 문제를 해결할 수 있도록 팀원들을 지도하고 멘토가 되어야 한다. 결코 프로덕션 코드를 작성할 필요가 없어야 한다. 코딩에 시간을 많이 할애하는 것은 비기능적인 궂은 일이다. 빌드를 더 빠르게 만들고, 공통된 코드들을 한 라이브러리로 추출해라. 팀의 일을 보다 생산적이고 재미있게 만들어 줄 수 있는 것들을 찾아라. 또한 사내에서 또는 개인적으로 개념 증명(Proofs Of Concepts) 코딩에 초점을 맞추거나 팀에서 사용할 신기술을 찾아본다거나 사이드 프로젝트를 진행함으로써 기술력을 유지시킬 수 있다.


나는 이 충고를 마음에 새겼고 그 결과에 더할 나위 없이 만족했다. 그 과정에서 내가 팀에서의 기술적 병목 현상이 아니란 사실을 알았을 뿐만 아니라, 팀원이 스스로 도전에 직면하고 배우면서 더 나은 개발자가 되어 스트레스를 덜 받게 되었다.


내 기술적 지식을 전달하기 위해 나는 흥미있는 주제에 관해 페어 코딩을 하고, 전 팀에 걸쳐 기술적 문제를 다같이 해결하거나 그저 기술적 지식과 의견을 공유하기 위한 “클린 코드 세션” 또한 운영한다.


요즘 내 코딩의 대부분은 Expedia(익스피디아 알렉사 스킬 같은), markpress 같은 사이드 프로젝트, 쓸모 없지만 쿨한 Rolex GMT 크롬 시작 탭 확장같은 사이드 프로젝트이다.



결 론


코딩까지 할 수 있는 관리자가 되는 것은 마치 투잡을 갖는 것과 같다. 매우 힘들고 또한 많은 헌신이 필요하다. 팀을 이끌고 성장시키는 것과 당신의 기술력 향상 사이에 균형이 잘 잡히지 않으면 벅차거나 지칠 것이다.


나는 리더십과 코딩을 모두 사랑해야 한다고 말하고 싶다. 관리자로서 또는 개발자로서 자신을 성장시키는 데에 더 많은 시간을 할애해야 하기 때문이다. 그러나 그만한 가치가 있다! 결국, 이런 게 삶 아니겠는가.



더 읽어볼 거리





편집자 주 : 이 아티클의 번역 및 배포를 위해 원저작자에게 연락을 했는데, 마침 원저작자인 Joan Gamell의 아내가 한국 분이라며 이 글의 번역 검토도 해주었습니다. 아울러, 함께 일하는 동료 중 한국 분이 이 글의 표현이 잘못 전달되지 않도록 여러 가지 제안도 해주셨습니다. 이 자리를 통해 다시 한번 감사드립니다.

또한 Joan Gamell은 이 글을 읽고 한국의 독자들은 어떤 생각을 하는지 나누고 싶어 합니다. 여러분의 생각과 경험 등을 함께 나누어 주시면 더 많은 사람들에게 도움이 될 것 같습니다. 


저작자 표시 비영리 동일 조건 변경 허락
신고

설정

트랙백

댓글









대표 번역가 : 오치문


개발자는 문제를 해결하는 사람이라고 믿는, 카페모카를 좋아하는 평범한 개발자.

현재 카카오 검색팀에서 일하고 있으며 문제를 깔끔하게 해결하는데 관심이 많다.


원문 링크





데이터 레이크


데이터 레이크(Data Lake)는 빅데이터(Big Data) 세계에서 데이터 분석 파이프 라인의 중요한 구성 요소 중 하나를 설명하기 위해 최근 10년간 등장한 용어입니다. 이것은 조직에서 누구나 분석할 때 필요한 모든 원시 데이터를 저장하는 단일 저장소를 갖는 것을 의미합니다. 일반적으로 사람들은 레이크(단일 저장소)의 데이터를 처리하기 위해서 하둡을 사용하지만, 데이터 레이크의 개념은 하둡보다 광범위합니다.

 

조직에서 분석하고자 하는 모든 데이터를 한 곳에 모은다고 들었을 때, 저는 바로 데이터 웨어하우스(그리고 데이터 마트[1])의 개념이 생각났습니다. 그러나 데이터 레이크와 데이터 웨어하우스 간에는 중요한 차이점이 있습니다. 데이터 레이크는 그것이 어떤 형태든, 데이터 소스가 제공하는 그대로의 원시 데이터를 저장합니다. 데이터 스키마에 대한 가정은 없으며 각 데이터 소스는 원하는 스키마를 사용할 수 있습니다. 따라서, 자신의 목적에 맞게 데이터를 이해하는 것은 데이터 소비자에게 달려있습니다.

Screen Shot 2017-06-29 at 11.08.09 AM.png

 

이것은 기존에 비해 진일보 한 것인데, 많은 데이터 웨어하우스들은 스키마 문제로 인해 멀리 가지 못했습니다. 데이터 웨어하우스는 모든 분석 요구에 대해 하나의 스키마 개념을 사용하는 경향이 있습니다. 저의 견해는 이런 단일 통합 데이터 모델은 아주 작은 조직을 제외하면 비현실적이라는 것입니다. 조금이라도 복잡한 도메인을 모델링하려면 각각의 데이터 모델과 함께 여러 개의 BoundedContext가 필요합니다. 분석 측면에서 보면, 자신이 수행 중인 분석에 적합한 모델을 사용하는 여러 분석가들이 필요합니다. 원시 데이터만 저장하도록 전환하면 데이터 분석가가 이 책임(각 컨텍스트에 맞게 이해하고 모델링 하는 것)을 지게 됩니다.

 

데이터 웨어하우스의 또 다른 문제점은 데이터 품질을 보장하는 것입니다. 데이터에 대해서 신뢰할 수 있는 하나의 소스를 얻으려면, 다른 시스템에서 어떻게 데이터를 수집하고 사용하는지에 대해 많은 분석이 필요합니다. 어떤 데이터에는 시스템 A가 좋고, 다른 데이터에는 시스템 B가 좋을 수 있습니다. 예를 들면, 시스템 A는 더 최근의 주문에 대해 좋을 수 있지만, 반품이 포함되지 않은 조건에서 한 달 또는 그 전의 주문에 대해서는 시스템 B가 더 좋을 수 있습니다. 무엇보다도, 데이터 품질은 종종 주관적인 문제이며, 각 분석마다 데이터 품질 문제에 대해 서로 다른 허용 오차를 가집니다. 심지어 무엇이 좋은 품질이냐에 대한 개념도 다릅니다.

 

이것은 데이터 레이크에 대한 흔한 비평을 야기합니다. 단지 광범위한, 다양한 품질의 데이터 쓰레기장이라는 것, 좋게 말해 데이터의 늪이라는 비평입니다. 비평은 타당하면서도 부적절합니다. 새로운 분석론에서 화제가 되고 있는 명칭이 ‘Data Scientist’입니다. 비록 이것이 남용되고 있는 명칭이지만, 여기에 속한 많은 사람들이 과학 분야에서 견고한 배경을 가지고 있습니다. 그리고 어떤 훌륭한 데이터 과학자는 데이터 품질 문제에 대해 모든 것을 알고 있습니다. 시간이 지남에 따라 온도 판독 값을 분석하는 간단한 문제를 생각해 봅시다. 측정치에 미묘하게 영향을 미치거나, 장비의 문제로 인한 이상, 센서가 작동하지 않는 기간 등의 이유로 일부 기상 관측소의 이전을 고려해야만 합니다. 하지만 많은 정교한 통계 기술이 데이터 품질 문제를 해결하기 위해 만들어졌기 때문에 이런 문제를 해결할 수 있습니다(즉, 어느 정도 오차가 있어도 관측소를 이전하지 않아도 됩니다). 데이터 과학자들은 항상 데이터 품질에 회의적이며, 의심스러운 데이터를 다루는 데 익숙합니다. 그래서 그들에게 데이터 레이크는 중요합니다. 왜냐하면 그들은 원시 데이터로 작업을 하고, 불명료한 데이터를 정제하는 메커니즘보다는, 데이터를 이해하기 위해서 더 나은 분석기술을 적용하는 것을 신중하게 고려해볼 수 있기 때문입니다.

(역자 주. 간단히 정리하면, 저자는 데이터 쓰레기장이라는 비평에 대해서, 데이터 레이크에 다양한 품질의 데이터가 섞여있는 것은 인정하지만 데이터 분석 기술로 커버할 수 있다는 것을 이야기 하고싶은 것같습니다.)

 

일반적으로 데이터 웨어하우스는 단순히 데이터를 정제하는 것뿐만 아니라 분석하기 용이한 형태로 모읍니다. 그러나 이 과정에서 데이터의 일부가 버려질 수 있기 때문에 데이터 과학자들은 이점에 대해서도 반대하는 경향이 있습니다. 데이터 레이크는 반드시 모든 데이터를 저장하고 있어야 하는데, 그 이유는 어떤 사람이 오늘 혹은 2년 내의 데이터에서 가치를 찾아낼지 모르기 때문입니다.

 

저의 동료 중 한 명이 최근의 한 사례를 들어 이 점에 대해 설명했습니다.

“우리는 우리의 자동 예측 모델과 회사의 계약 관리자들이 작성한 수동 예측을 비교하려고 했습니다. 그러기 위해서 우리의 모델을 당시의 데이터로 학습시키고, 우리의 예측 결과와 그 당시 관리자들의 예측 결과를 비교하려고 했습니다. 우리는 지금 정답을 알고 있기 때문에, 이 방법은 정확도 시험에 적합했습니다. 이 시험을 시작했을 때, 관리자들의 예측은 끔찍했고 불과 2주 만에 만들어진 우리의 단순한 모델 조차도 그들의 예측보다 나았습니다. 우리는 이 엄청난 성과를 사실로 받아 들이기에는 의심스럽다고 생각했습니다.

많은 테스트와 분석 후에 우리는 관리자의 예측들과 관련된 타임 스탬프가 잘못되었다는 것을 알게 되었습니다. 이 값들은 월 말 처리 보고서에 의해 수정되었던 것입니다. 간단히 말해서, 데이터 웨어하우스에 저장된 예측 값들은 쓸모가 없었습니다. 우리는 예측 비교를 수행할 방법이 없을 것이라고 우려했습니다. 더 많은 분석 후에 우리는 이 보고서가 저장되어 있는 것을 발견했고, 그 당시의 실제 예측을 추출할 수 있었습니다. (우리는 다시 관리자들의 예측보다 나은 결과를 얻었지만, 여기에 많은 시간이 필요했습니다).”

 

원시 데이터의 복잡성은 데이터를 보다 관리하기 쉬운 구조로 조정할 수 있는 여지가 있음을 의미합니다(또한 상당한 양의 데이터를 줄일 수 있습니다). 데이터 레이크에는 직접 접근하도록 해서는 안됩니다. 데이터 레이크에 저장된 가공되지 않은 데이터(원시 데이터)를 이해하기 위해서는 많은 기술이 필요합니다. 데이터 레이크를 이용해서 일하는 비교적 적은 사람들이 레이크에 있는 데이터로 일반적으로 유용한 뷰를 발견합니다. 또한 그들은 많은 양의 데이터 마트들을 만들어내는데, 각각의 데이터 마트는 하나의 bounded context에 맞는 특정한 모델을 갖습니다. 그렇게 되면 많은 다운스트림 사용자들이 이런 레이크쇼어 마트들을 각 컨텍스트에 맞는 신뢰성 있는 데이터 소스로 취급할 수 있습니다.

Screen Shot 2017-06-29 at 11.08.39 AM.png

지금까지 저는 데이터 레이크를 기업 전체의 데이터를 통합하는 단일 지점으로 설명했지만, 이것이 원래 의도 된 것은 아니라는 점을 이야기 해야겠습니다. 데이터 레이크는 James Dixon이 2010년에 처음으로 쓴 표현인데, 그의 의도는 데이터 레이크가 하나의 데이터 소스로 사용되는 것이고, 여러 개의 데이터 소스가 ‘water garden’으로 형성되는 것이었습니다. 이런 기원에도 불구하고, 지금은 일반적으로 데이터 레이크가 많은 데이터 소스들을 통합하는 것으로 사용되고 있습니다. [2]

 

데이터 레이크를 분석 목적으로만 사용하고 운영 시스템들 간의 연동을 위해 사용해서는 안됩니다. 운영 시스템과의 연동은 이 목적으로 설계된 RESTful HTTP 호출이나, 비동기 메시징 같은 서비스들을 이용해야 합니다. 데이터 레이크는 운영용 통신망으로 사용 하기에는 너무 복잡합니다. 데이터 레이크의 분석으로 인해 새로운 운영 통신 경로가 만들어질 수 있지만, 이런 것들은 데이터 레이크를 통해서 하기보다는 직접 구축해야 합니다.

 

데이터 레이크로 유입되는 모든 데이터가 장소와 시간에 대해 명확한 출처를 가져야 한다는 것은 매우 중요합니다. 모든 데이터에는 데이터가 어떤 시스템으로부터 유입되었는지, 그리고 언제 데이터가 생성 되었는지에 대한 명확한 흔적이 있어야 합니다. 그러므로 데이터 레이크는 역사적인 기록을 포함합니다. 이런 기록들은 아마도 Event Sourced 시스템과 자연스럽게 어울리는 도메인 이벤트들을 데이터 레이크에 저장할 때 발생할 것입니다. 하지만, 현재의 상태를 데이터 레이크로 정기적으로 덤핑하는 시스템에서도 역시 발생할 수 있습니다(소스 시스템에 시간과 관련된 것은 없지만, 시간에 따른 데이터 분석이 필요할 때 유용한 접근방식). 이에 따른 결과로, 데이터 레이크에 입력된 데이터는 변경되지 않고, 한 번 기술된 기록은 삭제될 수 없으며(나중에 잘못된 것으로 판별될 수는 있지만), Contradictory Observations(모순된 관찰)를 예상해야만 합니다(예를 들어, 같은 id로 처음에 들어온 값과 나중에 들어온 값이 달라질 수 있는 문제).

 

데이터 레이크는 스키마가 없으므로, 어떤 스키마를 사용할지는 소스 시스템에 달려 있고, 스키마가 없음으로 인해 발생하는 혼란을 처리하는 방법은 데이터 소비자가 결정해야 합니다. 게다가 소스 시스템은 자신이 유입시키는 데이터 스키마를 자유롭게 변경할 수 있으며, 소비자는 이에 대처해야 합니다. 당연히 우리는 가능한 한 최소한의 영향을 미치는 변화를 선호하지만, 데이터 과학자들은 데이터를 잃어버리는 것보다는 차라리 지저분한 데이터를 선호합니다.

 

데이터 레이크는 매우 커질 것이고, 저장소의 대부분은 스키마 없는 큰 규모의 구조를 지향합니다. 이것이 일반적으로 사람들이 데이터 레이크를 구현하는 기술로 하둡과 HDFS를 사용하는 이유입니다. 레이크쇼어  마트들의 중요한 작업 중 하나는 처리해야 하는 데이터의 양을 줄이는 것입니다. 그렇게 함으로써 대용량 데이터 분석에서는 많은 양의 데이터를 처리할 필요가 없게 됩니다.

 

원시 데이터의 범람에 대한 데이터 레이크의 욕망은 개인정보와 보안에 관해 난처한 질문을 야기합니다. Datensparsamkeit(독일어. 데이터를 캡처하고 저장하는 방법에 대한 자세로서 우리가 실제로 필요한 데이터만 처리해야 한다는 내용)의 원칙은 모든 데이터를 캡처하려는 데이터 과학자들의 욕구와 대치됩니다. 데이터 레이크는 공개된 바다를 선택하는 것을 좋아하는 크래커들에게 유혹의 대상이 됩니다. 소규모 데이터 과학 그룹에 한해서 데이터 레이크에 직접 접근하도록 제한하면 이 위협이 줄어들지만, 이 그룹이 항해 중인 데이터의 개인 정보 보호에 대해 어떻게 책임을 질 수 있는지에 대한 질문을 피할 수 없습니다.

 

 

Note

1 : 데이터 마트는 조직에서 단일 부서를 위한 것인 반면, 데이터 웨어하우스는 전 부서를 아우르는 통합을 위한 것이 일반적인 구분입니다. 데이터 웨어하우스가 모든 데이터 마트의 조합이 되어야 하는지, 아니면 데이터 마트를 데이터 웨어하우스에 존재하는 데이터의 논리적 하위 집합(뷰)으로 볼 것인지에 대해서는 서로 다른 의견들이 존재합니다.

 

2 : 이후의 블로그 포스트에서 Dixon은 데이터 레이크와 ‘water garden’의 구별을 강조하지만, (주석에서) 그것은 사소한 변화라고 말합니다. 제가 생각할 때 핵심은 데이터 레이크가 많은 양의 데이터를 가공되지 않은 상태로 저장한다는 것이고, 피더 스트림의 수는 별로 중요하지 않다는 것입니다.

 

감사 인사

Danielo Sato, David Johnston, Derek Hammer, Duncan Cragg, Jonny Leroy, Ken Collier, Shripad Agashe 및 Steven Lowe에게 내부 메일링 리스트에서 이 게시물의 초안을 논의한 것에 대해 감사의 말을 전합니다.

 

 

저작자 표시 비영리 동일 조건 변경 허락
신고

설정

트랙백

댓글

이 글은 미국에서 data scientist이고 machine learning 분야 박사학위자이며 현재 senior software engineer인 유시진(가명)님이 유학을 준비 중이거나 미국에서 IT 업체에 취업을 하고자 하는 개발자들에게 도움을 주고자 글을 작성하여 저에게 보내주신 내용을 제가 정리하여 공유해드리는 글입니다. 

​조금 더 많은 분들에게 도움을 드리고자 새롭게 시작한 브런치의 매거진에도 함께 공유를 합니다. 꼭 가명으로 올려달라고 하셔서 그냥 딱 생각난 이름을 도용했으니 많은 여성분들은 오해 없으시길 바랍니다.




이 글은 미국에서 구직 중이신 분들께 도움을 드리고 싶어서 썼습니다. 제가 그동안 구직 활동을 하면서 경험했던 것들을 정리해서 말씀드리겠습니다. 즉, 제 경험을 바탕으로 한 것이니 주관도 들어갈 수 있습니다. (본 글은 지원자가 미국에서 학교를 다니는 기준으로 하겠습니다.)


미국의 채용 과정(job process)은 다음과 같습니다.


일자리 지원(Job apply) -> 초기 전화 심사(Initial Phone Screen, 채용 담당자, 선택사항) -> 온라인 평가(Online assessment, 선택사항) -> 전화 인터뷰(Phone Interview) -> 현장 인터뷰(Onsite Interview) -> 일자리 제안(Offer)


1. 일자리 지원

회사에 지원하는 방법은 여러 가지가 있지만 제일 좋은 방법은

1.1 본인의 대학에서 열리는 채용 박람회(Career Fair)에 가는 겁니다. 이력서(Resume)를 주고 채용 담당자(Recruiter) 또는 엔지니어(Engineer)와 이야기를 나눌 건데 30초 안으로 자신의 강점을 말하는 게 중요합니다. 보통 회사는 대학 채용 박람회에 올 때 며칠 안으로 인터뷰를 진행하는 경우가 많습니다. 즉, 보다 빨리 채용될 수 있습니다.

1.2 두 번째 방법은 LinkedIn입니다. LinkedIn에서 job tab으로 들어가셔서 지원을 하거나 LinkedIn에 이력서를 상시 업데이트하면 채용 담당자에게서 연락이 자주 옵니다. 또는 본인이 가고 싶어 하는 회사의 엔지니어와 connection 요청을 하시는 것도 좋은 방법입니다. 채용 담당자에게 email로 직접 본인의 이력서와 원하는 job link를 문의하는 것도 좋습니다.

1.3 가장 보편적인 방법은 회사 웹사이트에 들어가서 지원하는 겁니다. 단점은 이 중 가장 시간이 오래 소요됩니다. 이력서가 수시로 들어오기 때문에 채용 담당자가 놓치는 경우가 많습니다.

1.4 제일 중요한 점은 각 팀마다 요구하는 기술사항이 다르므로 한 회사에서도 여러 군데에 본인이 원하는 직군에 이력서를 많이 보내는 게 좋습니다.


2. 초기 전화 심사(채용 담당자, 선택사항)

말씀드렸듯이 이는 선택사항입니다. 채용 담당자가 본인이 이 역할에 잘 맞는지 더 자세히 알기 위해 엔지니어와 인터뷰 전 전화로 이 사람이 업무를 잘 수행할 수 있는가 알아보는 시간을 갖습니다. 이를 통과하면 채용 담당자가 엔지니어 팀에 이력서를 넘기고 보통 팀 매니저가 결정을 합니다. 시간은 보통 10~15분 정도가 소요됩니다. 


3. 온라인 평가(선택사항)

요즘 온라인 평가(테스트)를 채택하는 회사들이 (e.g. Yelp, Amazon) 많습니다. https://www.hackerrank.com/ 사이트를 자주 사용하고요. 문제가 주어지고 본인이 원하는 프로그램 언어(program language)를 선택하신 후 algorithm을 작성하면 자동으로 사이트에서 채점을 합니다. 주어진 시간은 20분 ~ 1시간 정도입니다. Data structure를 공부했으면 그렇게 어렵지는 않지만 한국에서만 정규 교육을 받은 분들에게는 연습이 요구됩니다. 저도 한국에서 학부를 나왔지만 미국은 algorithm 구현하는데 수업을 많이 투자하기 때문에 처음에는 어렵습니다.


4. 전화 인터뷰

아마 가장 많이 접하실 거고 가장 많이 떨어지기도 하는 테스트입니다. 크게 인터뷰는 두 가지로 분류할 수 있습니다. 30분짜리 인터뷰이면 아마 지식 혹은 경험(knowledge) 부분만 물어볼 텐데 꽤 어렵습니다. 1시간짜리 인터뷰가 제일 보편적이고요, 10분 정도 이력서 심사(resume screen)를 하고 바로 코딩(coding) 문제로 들어가거나 지식 혹은 경험(knowledge) 부분을 조금 물어볼 수 있습니다. 코딩 테스트(coding test)를 할 때는 인터뷰어가 문제를 불러주고 본인이 인터넷을 통해 코딩을 하게 되는데 Google doc 같이 실시간으로 본인의 코드를 보게 됩니다. 이 중 주의할 부분은 인터뷰어가 중점으로 두는 사항은 (1) 문제를 잘 이해했는가? (2) 어떻게 문제에 접근하는가? (틀려도 좋습니다. 과정이 중요합니다.) (3) Big O notation에 대해서 잘 이해하는가? (4) Data structure에 대해서 잘 아는가? 를 가지고 판단합니다.

코딩을 할 때는 반드시 코딩만 하지 말고 "당신이 원하는 요구사항은 input이 이럴 때 이러한 output을 원하는가"를 꼭 물어보시고, 코딩을 하면서 "나는 data structure 중 linked list를 사용하겠다. 이유는 ~~~이고 timecomplexity는 이렇게 나올 것이다. 내가 만드려고 하는 algorithm은 대충 이러한 procedure를 가질 것이다"라고 먼저 설명을 한 다음 코드를 짜야합니다. 그리고 코드를 짜면서 꼭 말을 하면서 해야 합니다. 안 그러면 인터뷰어가 이 사람이 뭐하는 건지를 모르겠죠? 말을 하면서 코드를 짜야 본인을 더욱 어필할 수 있습니다. 코딩이 끝난 다음은 디버깅(debugging)을 해야 합니다. input에 어떤 값을 넣고 본인 코드에서 어떠한 일들이 일어나고 output으로 원하는 결과가 나온다는 것을 인터뷰어에게 디버깅하면서 보여주는 게 좋습니다.


말씀드리고 싶은 것이 많지만 간략하게 정리만 해 드리는 게 목적이므로 책을 소개하고 넘어가겠습니다.

https://www.amazon.com/Cracking-Coding-Interview-Fourth-Programming/dp/145157827X/?&&-14&+interview+questions

PDF로 찾으시면 다 나오고요, 다 보실 필요는 없고(1) Arrays and Strings (2) Linked Lists (3) Stacks and Queues (4) Trees and Graphs (5) Sorting and Searching (6) Recursion 정도만 공부하시면 도움이 많이 되실 겁니다.



5. 현장 인터뷰

전화 인터뷰를 잘 보셨으면 당일 ~ 일주일 내에 채용 담당자가 채용 인터뷰 초대를 할 겁니다. 현장 인터뷰는 직접 회사에 가서 시험을 보는 겁니다. 3시간 ~ 5시간 정도 소요되고요, 그 이상을 하는 경우도 있습니다. 비행기표와 호텔비, 식사비는 보통 회사에서 모두 지원을 합니다. 인터뷰는 칠판에 코딩을 하거나 지식 혹은 경험(knowledge)에 대해서 물어보는 식입니다. 코딩은 전화 인터뷰보다 어렵고요, http://www.geeksforgeeks.org/ 또는 leetcode.com에 나오는 문제 수준입니다. 지식 혹은 경험(knowledge) 부분은 아무래도 벼락치기는 상당히 어렵습니다. 저의 경우에 MapReduce를 인터뷰어가 전혀 모른다고 가정을 한 다음 칠판에 설명을 해보라는 식이었습니다. 그리고 시스템을 어떻게 구현할 것인지 아키텍처를 그려보라고도 하고, 아키텍처가 마음에 들면 세부적인(detail) 부분을 물어봅니다. 즉, 현장 인터뷰에서는 본인의 모든 실력을 다 발휘하셔야 합니다.


6. 일자리 제안

이 모든 것을 통과하시면 합격 통지를 받으시게 됩니다.


두서없이 썼네요. 아무튼 도움이 되셨길 바랍니다.



편집자 주 1 : 기고자께서 대부분의 용어를 영문으로 작성하여 주셨으나 가급적 읽기 편하게 한국어로 바꾸었으며, 프로그래밍 용어의 경우는 그대로 영문으로 표기해 었습니다.

편집자 주 2 : knowledge의 경우는 지식이라는 뜻도 있지만 아무래도 개발자의 경험 또한 인터뷰 당시 중요하게 보는 듯하여 '지식 혹은 경험'이라고 번역하였습니다. 

저작자 표시 비영리 동일 조건 변경 허락
신고

설정

트랙백

댓글


 



번역가 : 조인석


현재 중공업 필드에서 원격 플랜트의 주기기 모니터링 및 고장 예측 관련 업무를 수행하고 있다. 인공지능, 머신러닝 기반의 다양한 알고리즘과 인 메모리 기반의 Spark와 같은 빅 데이터 플랫폼 기술에 관심이 많다.

 

원문링크


역자주 : 본 글은 Martin Fowler가 회의록 형태로 작성한 글로써, 세 화자가 나눈 대화를 1인칭 관점에서 작성한 것을, 독자 여러분의 이해와 번역 분량 축소를 위해 대화 형태로 변경하여 번역 하였습니다.

 

 

TDD는 죽었는가?

 

본 글은 Martin Fowler, Kent Beck, David Heinemeier Hansson과 함께 Test-Driven Development (TDD) TDD  소프트웨어 설계에  미치는 영향에 관하여 나눈 대화입니다.

 


어디서부터 시작되었나


우리가 서로의 관점과 경험을 이해하기 위해 대화를 시작하게 된 것은 도발적인 발언과 블로그 포스트 때문이었습니다.

 

본 대화는 David Rails 커뮤니티에 TDD Unit Testing에 대한 언짢은 감정을 드러낸 David’s RailsConf keynote 로 인해 시작되었습니다. 그는 얼마 후에 몇 개의 블로그 포스트로 이어서 그의 견해를 정리했는데, 그 중 첫 번째 포스트가 바로 “TDD 죽었다(TDD is dead)” 입니다.

 

며칠 후, 저는 후속 포스트에 대한 오탈자 내역을 보냈고, 그는 그의 발언과 블로그 포스트에 대해 내가 어떤 생각을 가지고 있는지 알고 싶다고 말하였습니다. 그 후 우리는 Skype를 통해 한 시간 동안 즐겁고 사려 깊은 토론을 하였습니다. David Kent와도 비슷한 토론을 하였고, Kent는 우리 세 명이 함께 토론을 하고 대화 내용을 공개하자고 제안하였습니다. David는 그 생각을 트위터에 올렸고, 많은 사람들이 긍정적인 반응을 보였습니다.

 

우리는 단지 30분씩 6번 정도의 가벼운 대화가 오고 갈 것이라고 생각했었지, 이 시리즈에 대해 별 다른 계획을 하지 않았습니다. 우리는 그저 서로의 경험과 관점에 대해 배우기를 원했기 때문에 이번 일을 시작하였습니다 - 실은 많은 사람들이 우리를 봐주기를 바라는 자아도취에 빠진 사람들 같았죠. 우리는 초반 에피소드에서는 질문을 거의 받지 않았습니다만, 마지막 에피소드에서는 몇 개의 질문에 답변을 주었습니다. 우리는 우리가 이 토론을 진행하는 동안 블로그와 트위터를 통해서도 토론이 지속 되는 것을 즐겼습니다.


비디오 셋업과 행아웃 시간대를 조정해 준 ThoughtWorks Wesley Clock에게 감사의 말씀을 전합니다. 저는 각 에피소드가 끝날 때 마다 토론 내용을 그저 지켜보기 보다는 읽혀지기를 바라는 마음에 회의록을 작성하였습니다.

 

1: TDD와 확신

9 May 2014 / video / audio

우리는 TDD의 흐름에 대한 가지각색의 경험들과 사람들이 TDD와 자가-테스팅 코드를 종종 혼동하는 점에 대해 이야기 하였습니다.

 

회의록

David TDD와 단위테스팅에 대한 3 가지 주요 이슈를 띄우면서 토론을 시작하였습니다: 1) TDD와 단위테스팅의 정의에 대한 혼란, 2) TDD 구조를 준수하기 위해 사용한 mock객체들로 인한 테스트로 인한 손실, 그리고 3) TDD의 붉은색/초록색/리팩토링 사이클이 그에게는 무용지물이라는 것입니다. 저는 이해를 돕기 위해 TDD 등의 기원이 뭔지 아는 게 좋겠다고 의견을 냈는데, 이는 역사를 아는 것이 유용하기 때문이었습니다. 이에 Kent TDD의 기원에 대해 설명해주었습니다. 그는 스몰톡에서 여러 테스트 방식을 실험하기 시작했고 자기 성격에 TDD가 잘 맞았다고 합니다.

 

Martin : 우리가 C3에서 처음 함께 일하기 시작한 때가 생각나는 군요. 우리는 TDD를 사용하지는 않았지만, 각 프로그래밍 에피소드는 코드와 테스트가 함께 제공되었다고 장담합니다.

 

Kent : 프로그래머들은 그들이 작성한 코드가 잘 동작하는 것에 확신을 가져야 마땅하며, TDD가 그렇게 만드는 방법 중 하나(유일하지는 않은)이죠.

 

David : 저는 프로그래머의 행복을 위한 Ruby의 설계 목적을 좋아하고, 테스트 코드를 가지기 전까지는 일이 끝나지 않았다는 개념에는 동의합니다. - 하지만 TDD와 같은 방식으로 테스트 코드를 갖는 것을 선호하지는 않습니다. 사람들은 서로 사고방식이 달라서 서로 다른 기술과 언어를 좋아한다고 생각하고 있으며, TDD를 자가-테스팅 코드에서 얻을 수 있는 확신과 TDD라는 개념이 합쳐지는 것을 좋아하지 않습니다.

 

Kent : 최근 페이스북의 해커톤에서 절반은 TDD가 가능하였으나, 절반은 그렇지 않았었죠. TDD가 가능한 코드에서는 즐겁게 작업을 하고 있다는 것을 느꼈지만, 다른 절반에서는 그렇지 못 하다는 것을 느꼈었습니다. 하지만 non-TDD 파트에서도 여전히 저는 재발(regression) 테스트와 짧은 피드백 루프를 사용하였습니다. 저는 두 스타일을 함께 쓰는 것에 대해 별 다른 문제가 없었으며, 마치 클래식 음악과 재즈 음악을 함께 연주하는 것과 같았죠. TDD는 제가 학창시절에 수학을 어떻게 배웠는지 기억하게 해주었습니다 - 항상 예제가 필요했죠.

 

David : TDD가 잘 적용하여 개발을 한적도 있지만, 대부분의 저의 작업은 TDD가 잘 적용되지 않았습니다 - 제 질문은 “TDD를 적용함으로써 생기는 희생을 기꺼이 감수하는 이유가 무엇인가?”이죠. 많은 사람들이, 특히 무거운 mock객체 생성(mocking)으로 인해 나쁜 트레이드 오프를 합니다.

 

Kent : 다음 질문에 대한 트레이드오프에 대해 얘기 해보죠: 테스트가 가능한 중간 결과를 만들어내는 것이 가치가 있는 가?  컴파일러를 예를 들어보죠, 중간 구문분석-트리가 훌륭한 테스트 지점을 만들어주고, 더 좋은 설계입니다. 하지만 mock 객체에 대한 David의 질문에는 이렇게 대답하고 싶군요. 저는 mock객체를 거의 사용하지 않으며, 테스트는 리팩토링을 더 쉽게 해주는 반면, 목 객체는 종종 리팩토링을 더 어렵게 한다는 점이 좀 걱정 됩니다.

 

Martin : 저는 서로 다른 것이 뒤 섞이는 부분에서 전문 용어로 두 가지 문제점이 있다고 생각합니다.: 1) 첫째, TDD에 대한 David의 비평은 Mock객체를 사용해야 할 적합한 케이스가 아닌데도, 모든 TDD에 무거운 Mock객체를 써야만 한다는 가정을 하고 있습니다.; 2) 둘째, 자가-테스팅 코드와 TDD에는 차이점이 있습니다. TDD는 자가-테스팅 코드를 얻기 위한 한 가지 방법입니다.

 

David : 저의 TDD에 대한 반응은 무거운 mock 객체 스타일의 TDD를 도덕적으로 해야 한다고 말하는 사람들을 보았기 때문이며, 독립적인 단위 테스트를 가능하게 하기 위하여 비효율적으로 설계한 수 많은 코드들을 봤기 때문이죠.


Martin : 미리 정해놓은 시간에 따라 본 세션을 종료하겠습니다. 다음 세션에서는 어떻게 TDD가 손실을 발생시키는지, 진짜 손실인지, 어떻게 손실 유무를 판단 할 수 있는 지에 대해 논의 하겠습니다.

더 읽을 거리

·  이번 논의를 시작하게 된 David의 대화 (RailsConf talk).

·  David의 에세이 중 TDD는 죽었다(TDD is Dead) 와 테스트-유도 설계 손실(test-induced design damage).

·  Martin Flower가 얘기하는 자가-테스팅 코드(self-testing code)TDD의 차이점

·  Martin Flower의 단위테스트의 정의(defining unit tests).

 

2: 테스트로 인한 설계 손실

16 May 2014 / video / audio

David TDD를 사용하는 것이 hexagonal rails 와 같은 것에 도달하게 한다는 것을 느꼈습니다. hexagonal rails라 함은 지나친 간접 참조(indirection)로 인한 복잡성 때문에 테스트로 인한 설계 손실이 발생하는 경우를 말합니다. Kent는 이러한 현상이 TDD로 인한 것이라기 보다는 설계 결정에 대한 품질에 의한 것이라고 생각합니다.

 

본 대화를 보기 전에 David가 염려하는 설계 손실에 대한 예제(the gist David prepared)를 먼저 보십시오. 무척 그리운 Jim Weirich* hexagonal architecture 으로의 시도에 대한 동영상(explores this approach to a hexagonal architecture)도 보는 것을 권장합니다.

* 역자주) Jim Weirich 2014 2월에 타계하신 분이어서 무척 그립다(much-missed)라는 표현이 쓰였습니다.

 

회의록

Martin : , 이 질문으로 토론을 시작해보죠. TDD가 설계 손실을 발생 시킬 수 있나요? 손실이 실제로 손실로 이어 지나요? 어떻게 설계가 손실을 입었다고 판단할 수 있나요?

 

David : 저는 이 코드 예제(the gist he posted earlier)를 통해 답을 드릴 수 있겠네요. 사람들이 수 많은 mock객체를 사용하는 TDD를 쓰기 때문에 도달하게 되는 아키텍처를 예로 들어 보겠습니다. 애플리케이션의 각 레이어는 엄격하게 분리되어 있습니다. 가령, 컨트롤러는 실제 모델, 데이터베이스, 혹은 요청/응답 사이클을 사용 없이 테스트 할 수 있습니다. 그리 구체적인 예제를 보여주지는 않았습니다만, 단독 테스트를 쉽게 만들기 위해 너무나도 많은 불필요한 간접참조와 지나친 복잡도가 필요합니다.

 

Kent테스트-유도 손실을 TDD 탓으로 돌리는 것은 마치 자동차가 옳지 않은 장소에 주차되어 있다고 해서 차를 비난 하는 것과 같습니다. David가 보여준 설계는 TDD 때문이 아니었죠, 실제 이슈는 이러한 간접참조가 경우에 따라서 모두 좋은 트릭이 될 수 있다는 것이며, 우리는 이것이 가치가 있는지 없는지에 대해 이해할 필요가 있습니다.

 

David : 그 부분에 동의하지 않습니다. TDD (혹은 자동차)에 한번 올라 타면, 매번 기괴하고도 흉물스러운 테스트를 하게끔 명확한 길로 인도하고 있어요.

 

Kent : 그 부분은 설계 결정 이죠. TDD는 설계에 점진적인 영향을 줍니다, 사람들은 그들의 테스트 커버리지율이 얼마나 되는지에 대한 사항에 대해서는 호불호가 갈리죠David에게 묻겠습니다. gist 에서 보여준 어떠한 코드들이 시스템 구조를 어렵게 만드나요? (“누군가 신경 쓰는 무언가가 눈 앞에 있다면- 그때가 바로 문제가 되는 설계를 바꾸고 싶은 때입니다.)

 

David : 코드의 크기와 코드 변경 용이성간에는 명확한 상관관계가 있습니다. 이러한 모든 간접참조는 반드시 동기화가 되어야 하며, 10 라인의 코드가 60 라인의 코드보다 이해하기도 쉽고, 변경하기도 쉽죠. 간접참조의 모든 레이어는 높은 비용을 지불해야 합니다. TDD의 붉은색/초록색/리팩토링 흐름은 무척 중독성이 강하고 (Kent는 세상에서 가장 가난한 마약 중개업자임을 밝혔습니다.), 이 중독은 사람들이 좋지 못한 결정을 하게 만듭니다.

 

Martin : 저는 그 의견에 반대합니다. 이러한 상황 (이번 사례는 Rails) TDD 때문에 발생한 것이 아니라 hexagonal architecture의 핵심인 환경으로부터의 고립에 대한 바람에 의한 것이죠.

 

David : 사람들이 고립을 원하는 이유가 바로 TDD입니다. 고립에 대한 다양한 논쟁에 대해 들어왔고, 그 중에 테스팅을 위한 고립만이 의미가 있다는 것이죠. rails 애플리케이션을 커맨드-라인 애플리케이션으로 변경하는 건 터무니 없는 일이라고 생각하며, 비슷한 사례로 인-메모리 저장소와 웹 서비스 호출은 각각의 운영상 특징이 달라서 서로 교환할 수 없는 것과 같은 이치입니다. 이런 교환 가능성에 대한 꿈이 진짜 목적은 아닙니다. - 진짜 목적은 단독 테스팅이죠.

 

Kent : -메모리와 웹 서비스를 같은 걸로 대할 수 없다는 것에 동의합니다. (여러분은 아마도 분리했다고 생각 할 수 있지만, 정말로, 정말로 아닙니다. ) 실패 케이스가 서로 다르기 때문이죠. 요소들간의 경계는 무너지게 마련입니다. 질문은요소들간의 디커플링의 정도를 알아내는 데 얼마나 많은 시간을 할애하고 싶은가?”입니다10 라인 코드 내부의 응집도와 60 라인 코드 내부의 응집도도 서로 다르죠.

 

David : 그 의견에 동의합니다만, 응집도와 결합력은 언제나 대립됩니다. 좋은 응집도를 얻기 위한 결합력 상승의 대가는 대부분 가치가 있죠.

 

Kent : 외부 의존성을 제거하기 위해 다른 방법도 존재하며, 컴파일러와 같이 중간 결과를 활용 할 수도 있습니다. 설계 통찰이 필요한 간접참조는 테스트 하기가 어렵습니다만, 대부분 테스트 가능성을 높여주는 더 나은 설계를 하게 만드는 통찰을 찾는 것이 유용합니다.

 

David : 테스팅이 더 나은 설계를 만들어낼 수 있다는 것에는 동의합니다만, 저의 경험상 그렇지 못 한 경우도 잦았으며, 테스트 하기에는 좋지 않은 설계였습니다.

 

Kent : David 는 스스로에 대한 확신이 부족하군요, 오늘은 통찰을 볼 수 없을지도 모르겠습니다. 그러는 동안에도 앞으로 나아가기 위해 노력해야만 하고요. 하지만 당신의 낙관적인 시각 덕분에 우연히 나마 그러한 통찰들을 찾게 될 것입니다.

 

David : 저는 이런 상황을신앙적인 TDD”라 생각합니다 - 이러한 감정을 종종 느꼈습니다만, 존재하지 않는 이상적인 해결책을 찾지 못 할 때 빠지는 우울한 루프 안에 꼼짝없이 갇혀버렸었죠.

 

Kent : David TDD에 관해서 얘기하고 있지 않고 일반적인 소프트웨어 설계에 관하여 이야기하고 있군요, 당신의 문제는 TDD 때문이 아니라 어떻게 피드백을 받을 수 있느냐에 관한 문제라고 명확하게 말할 수 있습니다. 소프트웨어 설계에 관해 생각 해 봅시다. 좋은 설계 통찰로 인하여 얻을 수 있는 이득은 무척이나 크죠. 이러한 통찰을 얻는 다는 것은 당신의 작업 흐름에 관한 것이 아니라, 언제 일하고 언제 쉬고, 다른 장소로부터의 영향도를 파악하고 다른 사람들과 협업하는 방식에 대해 알아가는 것과 같습니다.

 

우리는 다음 번 주제를 통해 프로그래밍 중에 어떻게 피드백을 찾아낼 수 있는 지에 관한 트레이드오프에 관해 이야기 해보자고 말하면서 이번 세션을 마무리 하였습니다.

 

더 읽을 거리

·  David의 염려하는 설계 손실에 대한 예제(David's gist). gist Jim Weirich에 의한 대화(a talk by Jim Weirich)를 통해 주어진 hexagonal Rails 아키텍처의 탐구에 기초를 두고 있음.

·  David 의 블로그 포스트 중 테스트-유도 설계 손실의 문제점에 대한 소개(introducing the problem of test-induced design damage).

·  "hexagonal architecture" 라는 용어를 만든 Alistair Cockburn의 글(originally coined by Alistair Cockburn), “포트와 어댑터로도 소수 알려져 있음.

·  hexagonal Rails 아키텍처의 출현과 이를 사용하는데 있어서의 트레이드오프에 대한 Martin Flower의 글 (the nature of a hexagonal Rails architecture and trade-offs around using it).

 

3: 피드백과 QA

20 May 2014 / video / audio

우리는 프로그램을 하는 동안 피드백을 받고 QA로써 개발자에게 피드백을 주는 다양한 방법에 대해 토론하였습니다.

 

회의록

Kent : TDD를 수반하는 의사결정은 트레이드오프에 관한 것입니다.  “어떤 이상적인 세계에서는 우리의 프로그래밍 결정에 대하여 즉각적이고 틀림없는 피드백을 받기도 합니다.” … “내가 만든 모든 코드는 배포할 준비가 되었다면, 그 즉시 배포합니다.” 하지만 이러한 이상적인 상황은 현재 불가능하기 때문에, 질문은 바로이런 이상에서부터 얼마나 멀리 떨어져 있는가?” 라는 것이죠. 트레이드오프에 대한 여러 가지 제약 사항들을 나열해 보겠습니다.

·  빈번도: 얼마나 빨리 피드백을 받고 싶어 하나?

·  충실도: 얼마나 정확한 붉은색/초록색 신호를 원하나?

·  오버헤드: 얼마나 지불할 준비가 되어 있나?

·  수명: 이 소프트웨어의 라이프사이클은 어떤가? 시간과의 개연성이 얼마나 되는 가?

4개가 우리가 비교해 볼 필요가 있다고 생각하는 제약사항들입니다. 우리는 서로 동의하기 위해 이 행아웃에 참여하고 있는 것이 아닙니다 - 제 개인적인 목적은 단지 나의 아이디어를 건설적인 방식에서 멀찌감치 몰아내기 위해 준비 되어진 사람들에게 나의 의견을 명확하게 전달함으로써 서로의 트레이오프들에 대해 이해하는 것입니다.

 

Martin : 우리가 피드백을 받기 위해 살펴봐야 할 3가지에 대해 강조하고 싶습니다.

·  소프트웨어가 사용자에게 유용한 무언가를 하고 있나? 급여 계산과 같은 경우에는 테스트가 도움이 되지만, html 렌더링과 같은 경우에는 도움이 되지 않습니다.

·   내가 무언가를 망가뜨렸나? “이 부분에서 만큼은 자가-테스팅 코드는 마치 구세주이죠.” 저는 적어도 한번쯤은 모든 테스트가 실패하는 것을 보고 싶어요.

·  나의 코드-기반이 건강한가? 건강하다면 저는 빠르게 빌드를 계속 할 수 있습니다. 이 부분은 당신의 코드를 누가 인수 할지 명확하지 않을 때 더욱 까다로울 수 있습니다.

 

David : QA를 쓸모 없게 만드는데 TDD가 한 몫 했다는 주제를 제시하고 싶습니다. 많은 회사가 TDD를 택하고 QA을 없앴고, Basecamp 2년 전까지만 하더라도 QA가 없었습니다. 저는 TDD가 프로그래머들이나는 QA가 없다는 것에 대해 무척 자랑스러워라고 생각하게 만들었다고 생각하고 있었습니다. 오래된 모델이 제 기능을 동작하고 있지 못하고 있는 동안에, 시계 추는 너무나도 멀리 흔들리고 있었죠: “저는 당신이 물리적인 품질에 관한 어떤 작업도 수행 할 수 없다고 생각하며, 당신이 아닌 누군가가 테스트 하지 않는 한, 훌륭한 소프트웨어를 만들 수 없을 것이라고 생각합니다.” 저는 QA가 팀에 합류하는 것이 얼마나 강력한 힘을 발휘하는 지 보았기 때문에, 이러한 상황이 실망스러웠습니다.

 

David : 다른 이슈는 트레이드오프에 대해서 이해하려면 비용에 대해 반드시 이해해야 하고, TDD에 대한 모든 이야기는 TDD로 인한 이득에 관한 이야기이라는 것이죠. 이 비용을 고려 하지 않는 것 때문에, 사람들은 테스트로 인한 손실이 있다는 것을 충분히 이해하지 못하는 겁니다. 신뢰성에 대한 비용을 생각해봅시다: 99%에서 99.999%로 가는 것은 99%에 머무르는 것보다 기하급수적으로 많은 비용을 필요로 합니다. 높은 신뢰성은 우주 왕복선이나 레이스의 선두주자들에게나 중요한 이야기지, 실험적인 웹 사이트에게는 필요가 없습니다. 운영환경에서 사용하는 코드는 테스트 코드 없이 작성하지 않는 다는 규칙과 시스템의 중요성과는 상관관계가 없다고 봐야 합니다. (역자주: 시스템이 중요하지 않다고 해서 운영환경의 소스 코드를 테스트 코드 없이 작동해도 된다라는 건 옳지 않다는 뜻이네요.)

 

Kent : QA 에 관한 이슈로 돌아가보죠, QA와의 오래된 관계는 제대로 동작하지 않는 다고 생각합니다. 제 사무실의 페이스북에서 들고 나온 포스터에는페이스북에서는 어떠한 것도 다른 누간가의 문제점이 될 수 없다.”라고 말하고 있으며, 페이스북이 회사의 규모에 비해서 이 말을 잘 지키고 있다고 느끼고 있습니다. 페이스북은 최근까지도 QA가 없었으며 프로그래머는 QA에 대한 책임까지 가지고 있었습니다.  “그럼 무엇과 비교하실 건가요?” 라고 묻는 다면, 효과적인 QA를 가지는 것이 QA가 없는 것 보다는 낫지만, 과거의 제대로 동작하지 않는 관계라면 QA가 없는 것이 낫다고 생각합니다.

 

Martin : ThoughtWorks에서 일할 때 항상 QA가 있었습니다. 저도 역시 90년대와 비교해보면 잘 동작하지 않던 대립적인 관계도 사라졌고, 수작업으로 진행하던 스크립트 기반 테스트도 사라졌다는 것을 느끼고 있습니다. 그리고 스타트업들이 QA 없이 운영할 수 있는 건 그들 마음 이죠.

 

David : 초기 스피드를 위하여 심사숙고한 QA와의 트레이드오프에 대해서는 동의합니다만, 어떤 경우에는 프로그래머의 테스트가 지나칠 정도도 있어 왔으며, 실험적인 테스팅에서 어떠한 가치도 찾지 못 하기도 합니다. 만약 개발자들이 QA 없이도 충분히 높은 품질의 소프트웨어를 만들 수 있다면, 당신의 테스트들은 모두 초록색이겠지만, 운영환경에서의 사용자들은 당신이 예상하지 않았던 행동을 하게 마련이라는 거죠. 무엇보다 나쁜 것은 개발자들이 고객 서비스의 일부분이 아니라는 점입니다. 많은 프로그래머들은 단조롭고 지루하다는 이유로 전화 응대를 하고 싶어 하지 않습니다만, 그 또한 피드백 루프죠. 초록색 테스트를 통과한 코드는 당신이 원하는 범위 내에서는 안정기에 접어들었다고 할 수도 있습니다.

 

Kent : 이 제약사항에 관하여 다시 생각하기 위해 초록색 바 안에 빨간색 픽셀 몇 개를 심어야만 한다고 생각합니다. “전화 응대는 당신이 작성하지 않은 테스트를 가르쳐주기 위한 피드백 루프입니다.” 페이스북 프로그래머들은 전화응대를 해야만 하며, 모두들 그것에 대해 불평하고 있지만, 어느 누구도 전화응대를 피할 수는 없습니다. 당신이 더 이상 실수를 저지르지 않는다고 생각하는 그 순간, 그 것이 바로 실수이며, 당신은 성장 할 수 없습니다. 결국세상은 당신이 아무것도 망치지 않은 척 하게 내버려두지 않을 것입니다.” 저는 이른 새벽 2시에 받은 전화 한 통을 통해 꽤 값진 경험을 하였습니다.

 

Martin : 우리가 테스팅 비용에 관하여 더 이상 얘기하지 않는 것을 확인하고, 이번 세션을 마무리하였고, 다음 기회에 다시 한번 살펴 보자고 제안하였습니다. 또한 같은 주제로 Mike Bland가 제 사이트에 올린 을 보는 것도 좋을 것이라고 언급하였습니다.

 

4: 테스팅 비용

27 May 2014 / video / audio

우리는 테스팅과 TDD에 대한 덜 긍정적인 부분에 대해 토론하였습니다: 당신은 테스팅을 너무 지치게 하고 있지 않은가, 그리고 기능적인 코드보다 테스트에 더 많은 가치를 부여 하는 것이 팀에 문제가 되고 있는가?

 

회의록

David : 트레이드오프에 대해서 얘기하기 위해서는, 결점에 대해서 명확하게 이해하고 있어야만 합니다. 만약 결점이 없다면 트레이드오프도 없기 때문이죠. 저는 TDD가 어떤 것을 강제로 하라고 하지는 않지만, 명확한 방향으로 부추기고는 있습니다. 지나친 테스팅을 첫 번째 이슈로 얘기해보죠. 여러분은 결함 테스트가 없는 코드를 작성하면 안 된다는 얘기를 자주 듣죠, 처음에는 괜찮아 보입니다만, 지나친 테스팅을 하게 만들기도 합니다. 가령, 운영 코드의 매 라인을 위한 4 라인짜리 테스트 코드가 있는 것과 같은 것을 말하죠. 이 말은 당신이 무언가를 변경하려고 하면, 변경할 코드가 더 많아 진다는 뜻 입니다.

 

Kent : 사람들은 테스트 코드를 작성하기 위한 비용을 지불하는 것이 아니라, 충분히 확신을 하기 위해 작성하고 있는 것입니다.

 

David : 그럼 여러분(Kent Martin)은 운영 코드의 각 라인을 작성하기 전에 매번 테스트 코드를 작성하시나요?

 

Kent : 상황에 따라 다르죠, 그리고 이 대답은 흥미로운 질문들에 대한 모든 나의 답변의 시작부분과 같다고 할 수 있습니다. JUnit을 사용하는 운영 코드는 엄격하게 테스트 코드를 먼저 작성하게 되며, 이러한 과정 속에서 모습이 들어나는 자신의 모습(역자주 : 운영코드)으로 인해 무척이나 행복해합니다 - 그렇기 때문에 저는 TDD를 사용할 때 항상 지나친 테스팅을 하게 된다고 생각하지 않습니다.

 

Herb Derby : 델타 커버리지 개념에 대해 언급하고 싶군요 - 이러한 테스트는 중복되지 않는 비율이 얼마나 되나요? 제로 델타 커버리지 테스트는 그들이 의사소통 목적과 같은 것을 제공하지 않는 한, 제거되어야만 합니다. 저는 자주 system-y 테스트를 작성하고, 구현을 하며, 리팩토링을 거치고 나면, 결국 초기 테스트는 버려지게 되고 맙니다. 많은 사람들이 테스트들을 버리는 것에 대해 흥분하지만, 그들이 당신에게 아무것도 사주지 않는다면 당신도 흥분하게 될 것이라고도 했죠. 같은 것이 여러 방식으로 테스트 된다면, 그것이 바로 결합(커플링)이며 결합 비용이 발생합니다.

 

Martin : 지나친 테스트 코드는 분명 존재합니다, ThoughtWorks는 강한 테스팅 문화를 가지고 있기 때문에, ThoughtWorks에서도 발생하죠.  적정 수준의 테스트의 양을 정의하는 건 무척 어렵습니다. 어떨 때는 지나칠 때도 있고, 어떨 때는 적을 때도 있죠. 저는 가끔 지나치게 테스트하기를 원하며, 테스트가 너무 방대하지 않는 한 그렇게 하는 것에 있어 걱정하지 않습니다. 모든 라인의 코드를 테스트 하느냐라는 포인트에 대해서는 제가 다음 질문을 드리죠: “제가 이 코드를 망치는 것이 테스트를 실패하게 만드는 건가요?” 저는 때때로 고의로 코드 라인을 주석처리 하거나 조건을 반대로 바꾸고 나서 실패할 것이 확신한 테스트를 돌려보기도 합니다. 저의 반대쪽 머리의 (Kent로부터 온) 테스트는 그저 실패할 수도 있는 것들을 테스트하는 것입니다. 라이브러리들은 (정말 불안정하지 않는 한) 잘 동작한다고 가정합니다. 제가 라이브러리를 잘 못 사용하고 있는 지와 실수의 결과가 얼마나 심각한지 묻고 싶군요.

 

Kent : 테스트 코드 라인수와 운영 코드 라인수와의 비율은 믿기 어렵습니다. 저의 기억에 남는 경험은 Christopher Glaeser가 컴파일러를 작성하는 것을 보는 것이었으며, 그는 컴파일러 코드의 각 라인을 위한 4라인의 테스트 코드를 가지고 있었습니다. 간단한 시스템은 더욱 낮은 비율을 나타내겠죠.

 

David : 코드의 한 라인을 임시 주석 처리(comment out) 한 것이 눈에 띌 정도면 테스트 커버리지율이 100%라는 것을 의미합니다. 임시 주석 처리로 인한 소스 쪼개기가 어떤 경우에 값지다고 할 수 있는 지 생각해 봅시다. Rails의 선언적 주석문은 가치 있는 테스팅을 위하여 소스를 충분히 쪼개지 않습니다. 그렇기 때문에 저는 100% 이하의 커버리지율에도 충분히 만족합니다.

 

Martin : 만약 당신이 코드를 자신 있게 변경 할 수 없다면, 당신의 테스트는 (혹은 좋은 테스트) 충분하지 못 하다는 것을 의미합니다. 지나치다는 신호는 당신이 코드를 변경할 때, 코드를 변경하는 것 보다 테스트를 변경하는 노력이 더 많이 든다고 느낄 때를 말하는 거죠. 여러분은 Goldilocks zone* 안에 들어가길 원합니다만, 당신 혹은 당신의 팀이 어떠한 실수를 하는 경향이 있는 지와 누가 문제를 일으키지 않는 지에 대해 알아가는 경험과 함께 들어갈 수 있는 거죠. 저는 제가 확신이 없을 때코드의 한 라인을 임시 주석 처리 해도 되나라는 시도를 하는 것을 좋아하며, 그 시도가 시발점이지만, 그 환경에서 더 일하다 보면 더 나은 발견을 하게 됩니다. 

* 역자주> Goldilocks zone은 태양계에서 생명체가 살기 적합한 영역을 말합니다.


David : 이러한 튜닝은 잘 모르는 팀과 함께 코드를 제어하고 더 많은 테스트가 필요로 하는 컨설팅 팀과 상대적으로 더 안정적인 운영팀에게는 서로 다른 것으로 느껴지는 군요.

 

Kent : 테스트 우선 원칙에 대해 배운 것이 좋았으며, 그건 마치 까다로운 개발을 위한 4륜자동차의 저단 기어와 비슷한 거죠.

 

David : 다음 이슈로 넘어가보죠: 많은 사람들이 코드보다 문서화가 더 중요하다고 생각하곤 합니다. 지금 제가 걱정하는 것은 사람들이 기능 코드보다 테스트를 더 중요하게 생각한다는 것이죠. 이 부분은 TDD 사이클의 리팩토링 파트가 강조하는 부분과 연결이 됩니다. 이러한 모든 것들이 코드를 리팩토링하고 깨끗하게 유지 하는 것에 충분하지도 않은 에너지를 쏟아 붓게 만듭니다.

 

Kent : 운영 코드임에도 불구하고 버려졌지만, 테스트를 계속하고 재구현한 사례가 있습니다. 저는 새로운 코드가 잘 동작하고 있다는 것을 알려주는 테스트를 무척이나 좋아합니다.

 

David : 한 가지 흥미로운 질문이 떠오르는 군요: 꽤 많은 코드를 버리고 테스트 코드를 유지한 적이 있나요? 아니면 반대 상황이 있었나요? 각 상황에 맞는 답을 주셨으면 합니다.

 

Kent : 저는 테스트 코드를 읽을 때 코드가 어떻게 동작하는 지 쉽게 이해할 수 있습니다. 둘 중에 무엇이 더 중요하다고 생각하지는 않습니다 - 가장 중요한 포인트는 테스트 코드와 기능 코드가 서로 맞지 않으면, 그 부분에 에러가 있다는 것을 더블 체크 하는 것입니다. 저도 때로는 테스트 코드가 종료를 의미하는 것이기 때문에, 팀들이 사용자를 지원하는 것 보다 테스팅 환경에 더 많은 에너지를 쓰는 좋지 않은 상황을 만들기에 David의 의견에 동의합니다. 저는 코드가 완성되었을 때의 쾌감도 즐기지만, 가장 스릴이 넘치는 부분은 새로운 기능을 추가 했을 때죠, 속임수로 보일 수도 있지만, 코드 작성이 쉬워집니다. 이 모든 것들이 클린 코드에 의한 것입니다만, 코드를 깨끗하게 유지하는 거 하고, 쾌감을 느끼는 것 하곤 차이가 있습니다.


Kent Jeff Eastman를 비유로 설명하였습니다. 지문으로 담기에는 한계가 있군요. 그는 큰 설계 단순화를 설명하기 시작했습니다. 그는 신규 테스트가 동작하게 하는 것의 가치를 설명하는 것은 쉬우나, 설계를 깨끗하게 유지하는 것의 가치를 설명하기에는 어렵다고 말하였습니다.

 

David : 사람들은 정량적인 것들에 집중하기 마련이지만, 설계 품질을 숫자로 표현 할 수 없습니다 - 해서 사람들은 테스트 속도, 테스트 커버리지율, 테스트 비율 등에 대한 것 들은 우선순위에서 밀려나는 거죠. 이러한 것들은 꿀 팁과 같죠, 우리는 이러한 것들의 싸이렌 소리에 귀 기울일 필요가 있습니다. 운영 코드보다 테스팅 환경에 더 신경 쓰게 되는 것에 대하여 생각할 필요가 있습니다. 이는 오로지 비기술적인 이해당사자들에게만 유용한 지표가 될 수 있습니다. TDD를 파는 것이 중요하곤 했지만, TDD는 모든 것을 정복했으며, 우리는 TDD의 단점에 대해 살펴 볼 필요가 있습니다.

 

Martin : 저는 TDD가 지배적인 위치에 있었다고 생각하지 않습니다. 아직도 TDD를 적용하려고 하는 곳도 많거든요.

 

더 읽을 거리

·  측정을 잘못하는 경우의 토픽을 위해서 Pat Kua의 다음 글을 읽어 보세요. an appropriate use of metrics.

·   Martin Flower의 테스트 커버리지율의 사용법과 잘못된 사용법(use and misuse of test coverage).

 

5: Q&A

4 June 2014 / video / audio

우리는 시청자들의 질문에 답변을 주었습니다: TDD의 오픈소스 예제는 무엇인가, 우리가 TDD를 사용하는 방법을 변경하게 만드는 변화가 무엇인가, TDD를 경험하지 못한 개발자에게 TDD를 잘 적용하게 하는 방법은 무엇인가. 우리는 TDD의 건제함에 대한 관점에 대해 정리하면서 마무리 하였습니다.

 

회의록

Martin : 시청자들이 올려 놓은 질문 중 일부에 답변을 드리겠습니다. David Mike Harris “TDD를 활용한 오픈소스 프로젝트는 어떤 것이 있으며, 테스트-유도 설계 손실 혹은 TDD를 잘 활용한 사례가 있는가라는 질문에 답변을 드리는 걸로 본 세션을 시작하겠습니다.

 

David : 좋은 사례를 찾기 쉽지 않으며, 이 또한 논의 해볼만한 문제입니다. 우리에게는 일반적인 상황의 좋은 애플리케이션 사례가 없습니다. 왜냐하면 오픈소스 협력자들은 대개 개인적인 애플리케이션과 오픈소스 공통 프레임워크, 라이브러리들을 대상으로 작업하기 때문입니다. 다른 관점에서 이 논의의 결론을 내자면, 어떤 것이 실제로 의견충돌이 발생하는 것 보다 더 많은 의견충돌을 만들게 하는가에 대한 답이 필요합니다. 사람들은 철학적인 원칙보다는 실제 코드를 가지고 옵니다. 우리의 코드 예제는 사람들이 실제로 작업하고 있는 것에 비해서 그다지 중요하지 않습니다. 해서 당신은 설계 손실 설명을 위해 사용한 Jim Weirich의 예제를 위한 PT자료로 사람들을 이해해야만 합니다. 좋은 Rails 코드는 책에서 보여주는 표준 테스팅 방안에서 찾아 볼 수 있습니다.

 

Martin : 실제 코드를 이해하기 위해서는 많은 노력이 필요합니다. 저도 저희 팀의 코드 기반을 파고 들어가곤 합니다만, 무척 시간이 많이 걸리며, 팀과 일하는 경우 모두 같은 수준으로 이해하지 못합니다.

 

Kent : JUnit TDD를 엄격하게 사용하는 프로젝트 예제이며 잘 동작합니다. 하지만 이 논의의 좋은 예제로 들 수는 없겠군요. 왜냐하면 JUnit TDD를 위한 최고의 방안을 명확한 인터페이스를 통해 제공하기 때문입니다. 우리는 상이한 종류의 애플리케이션에 관해 얘기 하고 있습니다. 만약, 좋은 예제를 가지고 계신 분이 계시면, 꼭 내용을 공유해주시기 바랍니다.

 

David : 우리는 프로그래밍을 과학으로 대할 수 없습니다 - 우리는 기술을 객관적으로 평가 할 수 없습니다. 가치가 없는 논의를 하고 있다는 뜻은 아닙니다. 우리는 완전한 답을 얻을 수 없으며, 이치에 맞게 만드는 작업은 여러분의 몫입니다.

 

Kent : 동의합니다. 우리는 실험을 복제할 수는 없습니다만, 과학적인 사고방식으로 개개인이 바라볼 수는 있습니다. 우리는 우리 스스로 경험에 기반하여 시도해볼 수는 있겠습니다만, 일반적인 답변을 드릴 수는 없겠군요.

 

Martin : 다음 질문으로 넘어가겠습니다. Graham Lee님이 주신 질문입니다: Kent Martin에게 묻겠습니다. 소프트웨어 작성시 TDD를 사용하지 못 하게 하는 혹은 쓸모 없게 만드는 것은 무엇일까요? David에게는 이런 질문을 드리고 싶군요. 어떤 것이 TDD가 유용하게 동작하게 할 수 있을까요?

 

Kent : 제 포스트(RIP TDD post)를 한번 보시죠. TDD는 여러 문제점들을 해결하며, 확신을 갖기 시작하게 만듭니다. 또한 TDD는 문제점들을 작은 단위로 쪼개지게 해주며, 한번에 일반적인 문제를 해결하는 것 없이 구체적인 문제점을 걸고 넘어집니다. 저는 TDD가 단지 어렵다는 이유로 포기할 생각이 없습니다.

 

Martin : 저는 TDD를 쓸모 없게 만드는 것에 대해서 이야기 하기 보다는 다른 관점에서 TDD의 적용 가능성에 대해 말씀 드리겠습니다저는 훌륭한 설계를 우연히 접하였을 때 차분한 '신속한 느긋함'을 이용하여 기계적인 방식으로 TDD를 따르고 있습니다. 근래 대부분의 저의 프로그래밍은 제 웹 사이트 툴체인이며, 조금씩 진전이 있을 때마다 훌륭한 회귀 테스트가 딸려 있죠 - 저는 TDD 적용가능성을 찾지 못하였습니다. 하지만 제가 infodeck 코드를 빌드할 때면, TDD가 효과적이었던 애플리케이션이 있었습니다. 어떤 애플리케이션에서는 TDD가 무척 잘 들어 맞지만, 아닌 경우도 있습니다. 그리고 사람들은 그들의 성격을 애플리케이션에 반영하죠.

 

David : 제 경험도 비슷합니다. 저는 TDD를 통한 테스팅이 좋았고 모든 곳에 적용하려고 노력하였습니다만, MVC 웹 애플리케이션의 많은 영역에서는 TDD가 잘 맞지 않다는 것을 서서히 깨닫게 되었습니다. 이는 TDD가 어떤 상황에 대하여 효과적이 않다고 말씀 드리는 것이 아니고, 단지 제 작업의 작은 부분에 이런 사례가 있었다는 것입니다. 하지만 TDD를 사용하지 않게 되는 것이 자기-테스트 코드를 포기 하고 싶다는 것은 아닙니다 - 이것이 항상 저에게는TDD의 가치라고 생각합니다.

 

Martin : 제가 정확하게 TDD(혹은 어떤 기술)를 받아 들이는 방법을 알려드리겠습니다. 시험해 보고, 남용한 다음에, 여러분에게 잘 들어맞는 방식에 안착하세요. 그리고 조금 더 깊이 들여다보세요. “TDD는 자가-테스팅 코드를 향한 마약의 출입구입니다.”

 

Kent : 사람들은 결국 이러한 프로세스를 수행하는 작업 흐름을 가지게 됩니다. 제가 경험한 TDD David의 경험과는 다릅니다. 제가 개발할 때 어려운 부분을 만나게 되면, 저는 그 부분을 간단하게 만드는 명확한 체계를 가진 객체에 대한 아이디어를 얻습니다. TDD는 그러한 아이디어, 시도 그리고 API의 사용 예제와 구현 방법에 대한 피드백을 신속하게 가져다 주는 메커니즘을 제공합니다. 물론, TDD가 잘 맞지 않는 경우도 있죠. 그런 경우 command-R이 피드백을 받기 위한 좋은 방법인 것을 찾았습니다만, 그러한 순간에도 단순한 객체를 만들고 TDD를 시도하는 것을 원하기도 합니다.

 

Martin : Tudor Pavel님의 질문을 한번 볼까요? "경험이 적은 개발자들에게 TDD는 어떻게 동작합니까?" TDD는 사람들에게 작은 조각에 집중할 수 있게 강요하며, 인터페이스를 구현체로부터 분리하게 도와줍니다.  TDD가 훌륭한 결과를 보장해주지는 않습니다. 왜냐하면 경험 없이는 좋은 설계를 할 수 없기 때문이죠. 대개 경험이 적은 사람들이 TDD를 하는 경우에는 리팩토링을 충분히 하지 않으며, 적당히 최적화된 설계를 하게 마련입니다. 여러분은 경험이 없는 개발자의 산출물과 경험이 있는 개발자의 산출물은 비교할 수 없습니다. 반드시 경험이 없는 개발자가 TDD 없이 작업한 결과물과 비교 해야만 합니다. 비록 측정할 수는 없지만, 이로울 것으로 보이며, 나중에 리팩토링을 통해서 개선하는 것 보다 쉽게 자가 테스트 코드를 만듭니다. 해서, TDD는 여러분에게 좋은 시작점을 제공합니다.

 

David : TDD로부터 얻은 가치에 대해 말씀 드리겠습니다. TDD를 시작할 때, TDD는 훌륭한 학습도구였습니다. (하지만 이번 논의는 충분히 나아가고 있지 않는 듯 하군요.) 저는 사람들이 신규 인력들에게 그대로 따르지 않을지라도, 간단하고도, 직관적이고, 겉만 번지르르한 조언을 달라고 말할 때마다 회의적이었습니다. 이는 제가 가르치는 것에 대한 확신이 부족하다는 것을 보여줍니다.

 

Martin : 저는 그런 독단적인 내용에 대해서는 동의하지 않습니다. 저는 제가 설명하고 있는 것에 반하는 논쟁거리를 찾지 못할 때 의심을 갖게 됩니다. 여하튼, 우리는 신규 인력에게 소개 세션을 반복하고 있습니다. 어떤 사람들은 기초를 반복하는 것일 싫어하거든요.

 

David : 바로 이러한 것들 때문에 우리가 지금 대화를 나누고 있다고 생각합니다. 사람들은 그들의 의견을 기초에 더했다고 말하곤 합니다만, 10년 뒤에는 시작지점 보다 한참이나 내려오게 될 것이며, 좋은 장소에는 있지 못하게 됩니다. 여러분은 리셋 버튼을 누를 필요가 있으며, 대충 무마 하는 것처럼 보이지만, 효율적입니다. 제가 TDD가 죽었다고 말할 때, 저는 현재의 변화에 대해 언급하였습니다 - 우리는 첫 번째 원칙으로 돌아가야만 합니다.

 

Kent : 제가 David의 원래의 키노트에 대한 본능적인 반응을 보인 것이 바로 그 부분입니다. 프로그래머들은 빈번하게 같은 작업을 반복하고, 코드를 지나치게 복잡하게 만들며, 제대로 동작하지 않는 시스템과 씨름을 할 것입니다. 저는 첫 번째 원칙으로 돌아가자는 것에 동의하지만, 지난 10년간 프로그램에 관한 사람들의 기대감의 발전을 잃고 싶지는 않습니다여러분은 반드시 확신을 느낄 수 있어야 하며, 전진하고 있다고 주장 할 수 있어야 하고, 생산적이고 기술적으로 협업 할 수 있어야 합니다. 저는 경력이 시작할 무렵에는 무척 부족하였습니다만, 이제서야 모든 일을 스스로 하고 있다고 느끼고 있습니다.

 

David : TDD, XP 그리고 Ruby는 동시에 우리에게 다가왔습니다. 사람들은 프로그램은 즐거워야만 한다는 말에 비웃었지만, 저는 Rails를 개발하면서 그 말을 계속하고 싶었어요. 제 생각에는 Ruby 세상에서는 그 행복이 찾아온 듯 하군요 - 그 말이 이겼습니다 - 바로 애자일을 가졌기 때문이죠.

 

Martin : 저는 애자일이 이겼다는 것에는 동의할 수 없습니다 - 애자일이라는 라벨이 이긴거죠. 그러나 많은 사람들이 애자일을 한다고 말하지만, 실제로 하고 있지는 않아요. 저는 이런 전형적인 현상을 나타내는 프로세스를 의미적인 유포(semantic diffusion)라고 말합니다. 큰 승리는 오늘날 우리가 애자일을 고객과 공개적으로 할 수 있게 된 점이죠.

 

David : 이러한 재시도 문제점은 다른 것들도 있어요 - 10년 뒤에 여러분은 싫은 것이 많아 질겁니다. 2 가지 맛으로만 시작하였던 Pinkberry를 예로 들어볼까요? 지금은 다른 아이스크림들과 마찬가지로 복잡한 범위의 맛들을 가지고 있죠 - "대부분의 사람들은 좋은 아이디어를 혼자 내버려두지 않으려고 하죠"

 

Kent : 저는 David가 경험한 TDD를 여태 본적이 없어요. 저는 언제나 첫 번째 원칙으로부터 TDD를 적용해왔으니까요. 하지만, TDD에 붙어 있는 따개비들을 떼어내야 한다고 주의를 준 David에게 감사를 표합니다.


David : Rails에서 비슷한 이슈를 본 적이 있습니다. 저는 Rails를 기초적인 폼 안에서 사용해 왔는데, 제가 본 일부 Rails 코드는 충격적이었죠.

 

Kent : XP가 주목 받기 시작할 때의 최초 OOPSLA가 생각나는군요.

 

Jim Rumbauch : David는 앞으로 지난 10년 동안 XP*에 벌어진 일들을 깨닫지 못할 것입니다. (그는 옳았습니다.) TDD는 성공하였고, 다른 대안들은 날아오르지 못했죠기술이 내재하고 있는 어떤 것 때문에 혹은 기술을 잘 못 사용한 것 때문에 나쁜 현상이 벌어지고 있다고 말하는 것은 언제나 어려운 일입니다. 우리가 할 수 있는 건, 기초적인 것과 좋은 교훈을 꾸준히 반복하는 것뿐이죠.

*역자주> XP : eXtreme Programming, SW 개발 방법론 중 애자일 실천 방법 중 하나

 

David : 동의 합니다. 당신은 영웅으로 죽거나 악당이 될 수도 있겠죠. Ruby는 프로그래밍에 관하여 좋은 아이디어의 재시도였습니다. 함수형 프로그래밍은 또 다른 재시도이죠. 이러한 재시도들은 건강합니다. 저는 Rails TDD가 오랫동안 함께 해온 것에 감명 받았습니다. 저는 Rails 이전에는 PHP로 작업을 했어요. 여러분은 잘 만하면 PHP로 좋은 코드를 작성할 수 있으며, 다른 프로그래밍 언어들로도 힘을 북돋아주는 좋은 사례들을 만들 수 있다고 느낍니다. 저는 MVC 기반 웹 애플리케이션에 TDD를 잘 사용하는 것은 깨끗한 PHP 코드를 작성하는 것 보다 어렵다고 생각합니다.

 

Kent : 전 제가 언제든지 TDD를 사용할 수 있다고 믿기 때문에, 그렇지 않은 경우를 찾지 못하겠군요. 저는 언제든지 다른 길로도 TDD로의 탐험을 하길 원합니다. 저는 제 경험과 함께 꾸준히 탐험할 것입니다. 지나치게 많이도 해보고, 충분하지 않게도 해보고, goldilocks zone도 찾아보며, 근본적인 원인을 이해할 것입니다. 저는 명확하게 David의 의견에 반박합니다. TDD는 죽지 않았습니다. 하지만 David TDD에 불을 질렀고, 마치 불사조처럼 튀어 나오게 된 점에 대하여 기쁘게 생각합니다.

 

David : 제가 이 논의를 시작하게 된 이유는 사람들이 TDD가 효과적으로 사용되지 않는 케이스에 대해 이야기 하려고 하지 않았기 때문입니다. 그들은 기분이 좋지도 않았거나 확신이 없었음에도 불구하고 반드시 TDD를 사용해야만 한다고 말하곤 했죠. 저는 타당한 반응에 대한 영역을 열기를 원했고, 이로 인해 우리는 TDD가 적절한 지 아니면 적절하지 않은 지에 대해 논의 할 수 있었습니다. 인터넷의 많은 사람들이 TDD가 얼마나 좋은지 말하고 있지만, TDD가 그들에게 잘 동작하고 있지 않다고 말하는 것을 두려워하고 있었습니다. 저에게 자가-테스팅 코드는 우리가 TDD에 대해 미심쩍어 할 때에도 잃고 싶지 않는 존재입니다.

 

Martin : (처음 시작하기 전부터 기대 했듯이) 우리는 많은 부분에 동의하였습니다. 우리 모두는 자가-테스팅 코드에 많은 가치를 얻고 있으며, 우리 모두 TDD가 어떤 곳에서는 가치가 있지만, 얼마나 많은 곳에서 가치가 있는지에 대해서는 (비록 말하기 어렵지만) 일부 동의하지 못하였죠. 만약, 여러분이 소프트웨어 개발을 하고 있다면, 이 점에 대해 반드시 깊게 생각해야만 한다는 것 그리고 당신과 당신의 팀을 위하여 잘 맞는 사례를 찾아내야 만 한다는 것, 그리고 여러분은 장님처럼 아무 기술이나 가져다 쓰면 안 된다는 것에 의견이 좁혀졌다고 봅니다. 여러분은 TDD를 시도할 필요가 있으며, 사용해야 하며, 남용도 해보고, 여러분과 여러분의 팀에 잘 동작하는 것이 무엇인지 찾을 필요가 있습니다. 우리는 공식으로 뒤덮인 과학 안에 있지 않습니다. 그렇기에 우리 스스로의 경험 기반으로 함께 일을 해야만 합니다.

 

Martin Fowler

 

저작자 표시 비영리 동일 조건 변경 허락
신고

설정

트랙백

댓글


티스토리 툴바