> For the complete documentation index, see [llms.txt](https://jihunparkme.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jihunparkme.gitbook.io/docs/book/a-software-master.md).

# 소프트웨어 장인

[소프트웨어 장인](https://product.kyobobook.co.kr/detail/S000001889885) 책을 요약한 내용입니다.

<figure><img src="/files/SyycsT3ypdELKfqer2PO" alt=""><figcaption></figcaption></figure>

## Intro

겸손해져야 한다. 일을 끝내는 것 자체로는 부족하다. 그 일을 어떻게 하느냐가 더 중요하다. 자신이 하는 일 자체에 주의를 기울이자.

일을 어떻게 했느냐는 일을 해낸것만큼이나 중요하다.

[LSCC, London Software Craftsmanship Community](https://www.meetup.com/ko-KR/london-software-craftsmanship/)

## 애자일

"'애자일을 따른다는 것은' 새로운 환경에 성공적으로 적응하고 있다는 의미다."

* 애자일은 개발팀과 기업들이 변화에 적응할 수 있도록 변화와 관련도니 위험들을 줄여준다.
* 더 빨리, 더 짧게 피드백 루프를 만들수록 더 애자일해진다.

[애자일 매니페스토의 원칙들](https://medium.com/hgmin/agile-principles-%EC%95%A0%EC%9E%90%EC%9D%BC-12%EA%B0%80%EC%A7%80-%EC%9B%90%EC%B9%99-d3f386bd9839)

**절차적인 관점**

팀에 정말로 중요한 것, 비즈니스에 가치가 있는 것에 집중하여 올바른 목표를 향해 진행 중인지 확인

* 회의 방식
* 구성원 각각의 역할
* 요구사항 파악 방법
* 작업 진척 속도 파악 방법
* 점진적/반복적으로 일할 때 취하는 방식
* 진행 상황을 개발팀 밖의 관계자(고객, 영업 등)에게 전달하는 방식
* 비즈니스 피드백 방식

**기술적인 관점**

소프트웨어의 품질에 집중하여 팀이 결과물을 올바르게 만들어 가는지, 목표한 것을 올바르게 실행하고 있는지 안심할 수 있게 돕는다.

* 개발, 확장, 유지보수, 출시.. 에서 겪는 어려움들에 대해 특정한 기술적 관례나 기술 자체를 매우 구체적으로 가이드
  * TDD
  * 페어프로그래밍
  * 지속적인 통합

**애자일과 소프트웨어 장인정신**

기술적 탁월함의 개선 없이 절차만 개선하는 것은 무의미하다.

* 애자일은 기업의 반응속도를 높이고 기민하게 하며, 기업이 `올바른 일`을 하도록 돕는다.
* 소프트웨어 장인정신은 개발자와 기업들이 `일을 올바르게 수행`하도록 돕는다.

## 소프트웨어 장인정신

* 자신이 하는 일에 주인의식을 가지고 프로페셔널하게 행동하고, 고객이 원하는 것이 무엇이든 달성할 수 있도록 돕는 것
* 다른 개발자들에게 배우고 자신의 지식을 나누며, 경험이 부족한 개발자들을 멘토링하는 것
* 시켜야만 일하는 역량 미달의 노동자가 아니라 소프트웨어 프로페셔널의 수준을 높여, 프로의 모습으로 일하는 소프트웨어 개발자를 지향

  #### 매니페스토

  스프트웨어 장인을 열망하는 우리는, 스스로의 기술을 연마하고, 다른 사람들이 기술을 배울 수 있도록 도움으로써 **프로페셔널 소프트웨어 개발의 수준을 높인다.**

  **동작하는 소프트웨어뿐만 아니라, `정교하고 솜씨 있게 만들어진 작품을`.**

  * 좋은 소프트웨어라면 개발자가 쉽게 이해할 수 있어야 한다.
  * 높은 커버리지에 신뢰할 수 있는 테스트가 가능해야 하고, 명료하고 단순한 디자인과 비즈니스 용어로 잘 기술된 코드여야 한다.
  * 소스 코드는 예측가능하고 유지보수될 수 있는 상태여야 한다.
  * 개발자들이 애플리케이션을 수정하는 일을 부담스러워해서는 안 된다.

  **변화에 대응하는 것뿐만 아니라, `계속해서 가치를 더하는 것을`.**

  * 신규 기능을 추가하거나 버그 수정만을 뜻하지 않음
  * 코드를 깔끔하게 정리하고 구조를 개선하며 확장성을 높이고, 테스트 가능하게 하고, 쉽게 유지보수할 수 있게 하는 것을 포함
  * 소프트웨어가 오래될수록 고통과 비용이 아닌 그 가치가 커져야 한다.
  * 코드를 처음 발견했을 때보다 더 깨끗하게 관리하자.

  **개별적으로 협력하는 것뿐만 아니라, `프로페셔널 커뮤니티를 조성하는 것을`.**

  * 소프트웨어 장인은 항상 열정적으로 자기발전을 추구하고, 다음 세대의 장인을 준비시킬 책임이 있다.

  **고객과 협업하는 것뿐만 아니라, `생산적인 동반자 관계를`.**

  * 생산적인 동반자 관계는 어떤 순간이든 고객에게 가치를 제공하는 것을 의미한다.
  * 코드와 관련된 일이 아니면 나의 일이 아니라고 생각하는 개발자는 진정한 소프트웨어 장인이라고 할 수 없다.

## 소프트웨어 장인의 태도

* 오래 전에 작성했던 코드를 지금에 와서도 고칠 부분이 없어 보인다면, 그것은 그동안 배운 것이 없다는 뜻이다.
* 고객을 만족시키기 위한 투자는 스스로 해야 한다.
* 변화에 적응하고 계속해서 역량을 증진시키는 것은 소프트웨어 장인으로서 성공적인 커리어를 갖기 위한 열쇠다.

### 끊임없는 자기계발

**독서, 많은 독서**

특정 주제나 기술을 깊이 이해해야 할 때는 책만한 것이 없다.

* 특정 기술에 대한 서적
  * Java, Hibernate, Node.js, Clojure ..
* 특정 개념에 대한 서적
  * TDD, DDD, 객체 지향 설계, 함수형 프로그래밍, NoSQL 데이터베이스 모델 ..
* 행동양식에 대한 서적
  * 애자일 방법론, 소프트웨어 장인정신, 린 소프트웨어 개발, 심리학, 철학, 경영 ..
* 혁명적(or 고전) 서적
  * 실용주의 프로그래머, The Mythical Man-Month, 디자인 패턴, 테스트 주도 개발, 익스트림 프로그래밍, 클린 코더, 소프트웨어 장인정신, 리펙토링 ..

**블로그**

블로그를 이용하면 항상 최신 정보를 습득할 수 있다.

* 인스타페이퍼, 애버노트 ..

**기술 웹사이트**

기술 관련 웹사이트들도 시장의 최신 동향을 알아보기에 좋은 수단이다.

### 팔로우할 리더 찾기

그 기술을 진보시키고 더 나은 사용 방법들을 개발하고 있는지, 관련 업계를 어떤 사람이 움직이고 있는지 알아 두는 것이 좋다.

**소셜미디어**

트위터는 정보를 모으는 데 매우 유용하다.

### 끊임없는 훈련

훈련을 할 때는 그 문제를 '어떻게' 해결하는지가 중요하다.

* 더 많이 훈련할수록 더 편안해지고 별도의 주의 집중과 의식적인 노력이 없어도 자연스럽게 할 수 있게 된다.
* 훈련할 때는 그 훈련이 완벽하도록 노력해야 한다.

**카타**

* 소프트웨어 카타는 작은 훈련용 코딩들을 의미
* 훈련을 통해 우리가 익숙하지 못한 새로운 테크닉이나 기술에 능숙해질 수 있다.
* 같은 코딩 카타를 반복하더라도 매번 다른 테크닉, 다른 언어, 다른 기술, 다른 접근 방법을 사용해야 효과를 최대화할 수 있다.

**펫 프로젝트**

* 취미생활과도 비슷한 나만의 소프트웨어 프로젝트
* 어떤 실행 관례, 실행 원칙, 방법론, 기술을 배울지 정하고 그 다음에 그것을 이용해서 해결할 문제를 찾는다.
* 실제 프로젝트의 어떤 측면이든 배울 수 있다.

**오픈소스**

* 소스 코드를 내려받아, 실행해보고, 테스트 코드가 있다면 읽어본다. 디버깅해보기, 이용해보기, 기여할 부분이 보이면 작은 것부터 시작하자.
* 훌륭한 개발자들이 어떻게 일하는지 체험할 수 있다.

**페어 프로그래밍**

* 팀의 정신적 에너지가 높아지고 개발자들이 서로 좀더 친밀해질 수 있다.
* 새로운 내용을 빨리 배울 수 있다.
* 나 자신의 실제 역량을 파악하는 기회가 된다.

### 사회 활동: 다른 개발자들과 어울리기

사회적으로 교류할 수 있는 인적 네트워크를 형성하는 것은 성공적인 커리어를 위해 상당히 중요하다.

* 지역 사용자 그룹이나 기술 커뮤니티에 가입하고 행사들에 참여하면 인적 네트워크를 쉽게 만들 수 있다.
* 무언가를 배우고 아이디어를 나누기에 더할 나위 없이 좋은 방법이다.

## 의도한 발견

아직 배울 내용이 많음을 인정하는 것은 성숙하다는 증거이고 마스터가 되기 위한 첫걸음이다.

* 현재 처한 상황과 관련해 새로운 사실들을 계속 익히도록 스스로를 노출시키자.
* 모르는 것을 배우는 기회를 만들기 위해 항상 노력해야 한다.
* '무지'라는 장애요소를 제거하는 것은 우선순위에서 높이 두어야 한다.
* 무지에 대항하는 습관을 들이면 프로페셔널로 성장하는 데 큰 도움이 된다.

### 일과 삶의 균형

커리어를 위해 업무 외 시간에 학습과 훈련을 게을리하지 않는 것이 중요하다.

* 한 주에 하루 정도는 출근 전에 카페에서 한 두 시간 동안 자기계발을 해보자.
* 사용자 그룹이나 기술 커뮤니티가 근처에 있다면 참여해보자.
* 혼자서 학습해서 배울 수 있는 것에는 한계가 있다.
* 침대에서 평소보다 30분 정도 일찍 들어서 잠들기 전에 독서를 하거나, 블로그를 보거나, 기술 관련 스크린 캐스트들을 보자.

**집중 - 뽀모도로 기법**

* 시간을 쓰기 전에 그 시간을 어디에 쓸지 미리 정해두는 것이 좋다.
* 뽀모도로 기법을 적용하면 효과적이다.
  * 어떤 일을 할지 정하자.
  * 뽀모도로(타이머)를 25분에 맞추자.
  * 타이머가 끝날 때까지 그 일을 하자.
  * 짧게 쉬자(보통 5분정도)
  * 매 4회의 '뽀모도로'마다 길게 쉬자.(15\~30분)

**균형**

* 무엇을 하든지 페이스를 유지하는 것이 중요하다.
* 좋은 인적 네트워크를 가지고 시장이 요구하는 기술을 습득하고 있다면, 프로페셔널로서의 삶에 대해서 크게 걱정하지 않아도 된다.

> 성공적인 커리어를 가지려면 `결단력`과 `열정`이 필요하다.
>
> `배움`과 `훈련`이 멈추는 순간 우리의 커리어도 멈춰버린다.
>
> 우리는 모두 정확히 같은 만큼의 시간이 주어진다. 차이점은 우리가 그 시간을 어떻게 쓰느냐일 뿐이다.

## 영웅, 선의 그리고 프로페셔널리즘

**`아니오`라고 말하는 방법 배우기**

* 이미 불가능하다고 알고 있는 것에 대해 '해보겠다'라고 말하지 말아야 한다.

**프로답게 행동하기**

* 빡빡한 일정으르 다루는 가장 좋은 방법은 필요한 모든 것을 분석하여 가능한 위험과 우려사항을 터놓고 관계자들과 소통하는 것이다.
* 불명확하거나 불편한 사실들, 걱정되는 사항들을 최대한 이른 시점에 문제제기해야 한다.
* 그저 실망시키지 않기 위해 말하는 '네'는 거짓말에 지나지 않는다.
* 프로페셔널리즘은 나 자신과 팀 동료들 그리고 관리자들과 고객들에게 정직함을 의미한다.
* 다툼을 피하지 말고 부딪혀서 어려운 결정을 내릴 수 있어야 한다.

**대안 제시**

항상 '아니오'라고만 얘기하는 것은 프로다운 태도가 아니다.

* 모든 '아니오'에는 반드시 하나 이상의 대안들이 따라와야 한다.
* 우리가 '아니오'라고 대답해야 하는 상황에서도 항상 '네'라고 말할 방안을 탐색해야 한다.
* 문제를 어떻게 풀어야 할지 방법을 모른다면, 진척 상황을 가능한 자주 공유하는 것이 할 수 있는 최선의 방법이다.

**깨어있는 관리자**

* 훌륭한 관리자들은 자신이 개발팀의 일부이며 개발자들과 함께 공동의 목표를 위해 일한다는 것을 이해한다.
* 문제를 숨기지 않고 드러내는 태도는 모두가 하나의 팀으로서 공동의 목표를 위해 일하고 있다는 징표다.
* 좋은 관리자는 외부의 압력으로부터 개발자를 보호하고 팀이 가진 장애요소들을 제거한다.
* 팀원들이 편안한 마음으로 자신감을 갖고 일할 수 있도록 해준다.
* 팀을 건강하고 행복하고 단결되게 하는 것은 관리자의 직무다.

## 동작하는 소프트웨어

동작하는 소프트웨어만으로는 부족하다

**정원 돌보기**

> 프로그래밍은 집을 짓는다기보다는 정원을 돌보는 것에 더 가깝다 - 실용주의 프로그래머

* 코드는 정원처럼 지속적인 유지보수가 필요하다.
* 기본적이고 정기적인 유지보수만으로도 정원을 훌륭하게 가꿀 수 있다.

**보이지 않는 위협**

* 비즈니스의 기민함과 투자 효율을 높이기 위해서는 다른 무엇보다도 코드의 품질이 가장 중요하다.
* 장인은 꾸준히 코드 베이스를 돌보고 두려움 없이 빠르게 리펙토링한다.
* 전체 애플리케이션을 몇 분만에 테스트할 수 있는 자동화 테스트를 구축하고 활용할 줄 안다.
* 코드의 품질이 프로젝트의 성공을 보증하지는 못하더라도 실패의 핵심 요인이 될 수 있다.

**시간에 대한 잘못된 인식**

* 단위 테스트는 우리가 코드를 작성하는 방식에 이미 녹아있는 것이지 별도의 작업이 아니다.
* 우리가 공식적인 작업 일정표에 무언가를 올려 놓는다는 것은 제품 오너가 그중 중요하지 않다고 생각하는 것을 삭제할 수 있는 권리를 준다는 것과 같다.
* 항상 프로젝트에 다른 사람들도 있다는 사실을 인식하고 전체 프로젝트에 미치는 영향을 감안하여 책임있게 행동해야 한다.

**효율적인 시간 활용**

* 언제, 어떤 코드든 쉽게 테스트하고 통합할 수 있도록 주변을 잘 정리해야만 한다.
* 수동 테스트, 디버깅, 오래 걸리는 빌드, 까다로운 애플리케이션 배포, 복잡한 프로젝트 개발 환경 설정같은 것에 시간을 덜 빼앗길수록 애플리케이션의 품질에 더 신경을 쓸 수 있고 고객을 행복하게 할 수 있다.

**레거시 코드**

> 태도는 큰 차이를 가져올 수 있는 작은 요소다 - Winston Churchill

**태도의 변화**

> 무언가가 마음에 들지 않는다면 바꾸어라.
>
> 그것을 바꿀 수 없다면, 그에 대한 당신의 생각을 바꾸어라. - Mary Engelbreit

* 무언가 나아지길 원한다면 그에 맞는 행동을 취해야 한다.
* 레거시 코드를 재미있고 도전적인 문제로 바라보자.
* 일을 즐길 수 있느냐 없느냐는 우리의 태도에 달려 있다.

## 기술적 실행 관례

**올바른 일 vs 올바른 실행**

* 애자일 방법론은 빠르고 짦은 피드백 루프를 제공하여 우리가 '올바른 일(Right Things)\`을 실행하고 있는지 점검하도록 도와준다.

**상황 논리**

* XP 실행 관례에는 테스트 주도 개발, 페어 프로그래밍, 리펙토링, 단순한 디자인, 지속적인 통합 등..
* 일하는 방식을 바꾸기 전에 우리가 어떤 상황에 놓여 있는지 파악하는 것은 중요

**실행 관례와 가치**

* XP 실행 관계들은 소프트웨어의 품질, 즉 일을 올바르게 수행하는 관점에서 피드백 루프를 단축시킬 수 있는 여러 방법을 제공
* 실행 관례의 도입 자체를 관리자나 팀 구성원들에게 설득하려 하지 말고 현재 일하는 방식과 비교해서 그것이 가져올 이익에 집중해야 한다.
* 빠른 피드백 루프, 요구사항과 비용에 대한 더 나은 이해, 지식 공유, 줄어드는 버그, 전체적으로 자동화되고 릴리즈가 빨라지는 일들이 기술적 실행 관례를 도입함으로써 얻을 수 있는 가치들

XP 실행 관례의 일부를 살펴보자.

* 자동화된 테스트
  * 클릭 한 번으로 전체 시스템을 단 몇 분만에 검증
  * 실제 측정 가능한 비즈니스적 가치를 가져다 준다
* 테스트 먼저
  * 테스트 코드를 먼저 작성하기
  * 아이디어를 생각해내는 데도 도움이 되고 한 번에 하나씩만 집중이 가능
* 테스트 주도 개발
  * 설계에 대한 실행 관례
  * 정확히 요구사항만큼만 만족시키므로 테스트로 규정된 부분만 작성
  * 코드가 복잡하고 방대하면 테스트 자체가 어렵기 때문에 설계를 재검토하고 단순하게 리펙토링하는 긍정적인 원인을 제공
  * 코드의 설계, 단순성, 유지보수 용이성에 대해 피드백이 빠르고, 코드에 대한 살아 움직이는 문서 역할
* 지속가능한 통합
  * 지속적인 통합은 TDD와 함께 수행되어 오랜 시간의 피드백 루프를 단 몇 분으로 줄일 수 있음
  * 일단 멈추고 버그부터 수정한다는 태도가 필요
* 페어 프로그래밍
  * 코드가 작성되자마자 그 품질에 대한 피드백을 받을 수 있음
  * 주기적인 페어의 변경은 전체 시스템에 대한 이해도나 개발자의 스킬이 팀 차원에서 누적되어 올라간다
* 리펙토링
  * 엉망인 코드가 많을수록 엉망인 코드가 늘어나는 속도도 빨라진다
  * 지속적으로 코드를 리펙토링하면 이러한 위험이 줄어든다
  * 더 자주 변경되는 부분을 대상으로 시작하고, 해당 부분을 이해하여 변경할 필요가 있을 때 적용하자
  * 유지보수가 쉬운 깨끗한 코드는 개발 속도를 높이고 버그가 만들어질 가능성을 낮춘다

**실용주의**

실용주의는 소트웨어 장인이 가져야 하는 최선의 역량 중 하나

* 어떤 실행 관례가 더 나은지 알아보는 가장 좋은 방법은 프로젝트에 어떤 가치를 주는지, 피드백 루프가 얼마나 긴지를 비교해 보는 것
* 소프트웨어 장인으로서 우리의 일에 항상 최선의 기술, 도구, 절차, 방법론 그리고 실행 관례를 선택할 수 있도록 개방적인 사고 방식을 가지자
* 실행 관례에 대한 도입을 이갸기하기 전에 먼저 우리가 이루려는 것이 무엇인지 논의해보자

## 길고 긴 여정

편안하고 익숙한 상태에서 벗어나 나를 발전시키고 배울 수 있는 기회를 지속적으로 찾아보자

**결단과 집중**

> 어디로 가고 있는지 모르고 있다면, 결국 가고 싶지 않은 곳으로 간다. - Yogi Berra

* 어디로 가기를 원하는지 커리어의 방향을 정하는 것이 중요하다.

어디로 가고 싶은지 커리어의 방향을 확신할 수 없다면 기회를 만들어 내기 위해 할 수 있는 모든 문들을 열어보길 시작하자.

* 익숙하고 편한 것에서 벗어나 새로운 것(새로운 프로그래밍 언어나 기술)을 공부하고 기술적 지식 확장하기.
* 지역 커뮤니티에 정기적으로 출석하거나 행사에 참여하기
* 다른 개발자, 비즈니스맨들과 교류하기
* 새롭게 배운 것, 지금 하고 있는 것들에 대해 블로깅하기
* 오픈 소스 프로젝트에 참여하기
* 프로젝트를 만들고 공개하기
* 콘퍼런스 참석하기
* 콘퍼런스 연사로 나가기

**투자로서의 일터**

거쳐가는 모든 직장, 프로젝트들 하나 하나를 투자로 인식하는 것이 가장 중요

* 우리가 기대하는 보상이 어떠한 것인지 명확히 하기
* 스스로를 낯선 환경에 노출시켜서 새로운 것을 배우고, 일을 수행하는 다른 방법들을 알아가기
* 지식은 일에서 얻을 수 있는 가장 흔한 투자 이익이다.
* 항상 배우고 더 나은 소프트웨어 장인이 되는 것에 집중한다면, 단순히 돈만 쫓을 때보다 좋은 직장을 얻기가 오히려 더 수월하다.

**자율성, 통달, 목적의식**

* 자율성 : 우리가 무엇을, 어떻게, 언제할지 통제할 수 있는 상태
  * 제대로 된 애자일 개발 환경이라면 이러한 것들이 보장되어야 함
* 통달 : 더 나은 프로페셔널, 더 나은 인간이 되기 위해 계속 배우고 진화하는 것
* 목적의식 : 지금 하고 있는 일이 중요하고, 무언가를 더 나아지게 하고 있다고 느끼는 것
  * 아무런 이해없이 시키는 대로 일하는 것의 반대 개념

**회사 안에서의 커리어**

* 어떤 계단을 밟느냐는 새로운 직장을 얻기 전에 숙제를 얼마나 잘 해놓았느냐에 달려 있다.
* 소프트웨어 장인은 그를의 커리어가 긴 여정이며, 어떤 종착지에 도달하는 것보다 그 여정 자체가 훨씬 더 중요함을 안다.

> 일을 할 때는 자율성, 통잘, 목적의식을 쫒자.
>
> 성공적인 커리어는 꽁짜로 오지 않는다. 스스로 만들어 나가야 한다.
>
> 일을 신중히 선택하고 고객들을 만족시켜 나가면, 소프트웨어 장인으로서 매우 성공적이고 즐거운 커리어를 만들 수 있다.

## 인재 채용

훌륭한 개발자를 유인하려면 먼저 채용 공고의 직무 요건을 바로잡아야 한다.

* 어떤 조직의 문화와 정체성은 회사의 구성원이 결정한다.
* 훌륭한 개발자들에게 일은 그냥 일이 아니다. 일은 취미이자 열정이다.
* 미래의 성공 가능성을 높이기 위해서는 열정적인 개발자를 찾아야 한다.

**인터뷰 시간에 대한 변명**

* 면접에 투자할 시간이 없다는 것은 훌륭한 팀을 구성하는 것을 소홀히 한다는 것과 같다.

**틀에 박힌 직무 요건**

* 채용 공고에 직무 요건 목록을 기술하는 방식은 피해야 할 관례다.
  * 절대적인 숫자: 몇 년간 \~ 경력
  * 키워드 매칭: 특정 기술이나 플랫폼
  * 기술 목록의 나열
  * 잘못된 기업 문화 설명
  * 잘못된 요구 항목: 기술, 경력 년수, 일한 산업군, 학벌
  * 잘못된 선별 조건
  * 승진 요건과 불일치

**추천 채용**

* 추천 채용 시스템에 금전 보상이 더해지면 채용 절차 전체를 무효화할만한 잘못된 동기가 생길 수 있다.
* 좋은 개발자들은 좋은 개발자들과 일하고 싶어하는 동기 하나만이 의미가 있다.

**커뮤니티 활용**

* 재능있는 개발자들을 채용하기 위한 최선의 방법은 여러 개발자 커뮤니티와 접촉하는 것이다.
* 사용자 그룹과 기술 커뮤니티들은 정기적으로 모임을 갖기 떄문에 개발자들과 회사들 모두 쉽게 함께할 기회를 찾을 수 있다.

## 소프트웨어 장인 면접하기

**비즈니스 협상**

* 면접을 볼 때, 일자리를 구걸하는 입장이 아니라는 것을 기억하자. 비즈니스 협상을 하는 것이다.

**생산적인 파트너십을 알아보는 방법**

회사 입장에서의 관점

* 우리가 하는 일에 대해서 여러 관심의 질문들을 던지고, 일하는 방식을 개선하여 목표를 성공적으로 달성하는데 기여하기를 원함
* "어떤 식으로 일하는지, 무엇을 성취하길 원하는지, 당면한 문제가 무엇인지 등에 대해 면접 때조차 아무런 질문도 하지 않은 사람이, 실제 업무 현장에서 갑자기 적극적으로 질문을 하리라고 기대할 수 있을까?"
* 지원자가 일과 회사에 대해 아무런 질문도 하지 않는다면 단지 '아무 일자리'나 찾고 있을 뿐이라는 신호가 될 수 있음
* 그 반대라면, 최소한 지원자 스스로 즐겁게 일할 수 있는 곳을 찾고 있다는 증거가 될 수 있음
  * 과거 수행한 프로젝트나 업무, 기술 또는 스스로 성취한 사항들을 이야기할 때 열정적이고 애착이 보이는가
  * 실패 사례에 대해서 어떻게 표현하는가
  * 실패에 대해서 책임감을 느끼는가. 혹은 남탓을 하는가
  * 잘못된 상황을 정상으로 되돌리기 위해 무엇이든 노력을 해보았는가
  * 이전 업무에서 불평 불만 대신 그 상황을 개선하기 위해 스스로 노력했는가
  * 어떤 종류의 업무 환경을 찾고 있는가
  * 회사에서 그러한 환경을 제공해줄 수 있는가
  * ...
* 지원자에게 회사와 프로젝트에 관해 설명할 때는 좋은 점은 물론 나쁜 점, 껄끄러운 부분까지 가급적 모두 말해야 한다
* 지원자가 채용되고 일을 시작할 때 그가 사전에 기대한 것에서 크게 어긋나지 않도록 해야 한다

지원자 입장에서의 관점

* 그 회사와 같이 일하게 될 회사의 사람들에 대해 알 수 있는 대단히 중요한 기회
* 면접에서 관심을 두어야 할 사항들.
  * 면접관(프로젝트 관리자, 개발자, 림 리터, 아키텍트)은 누구인가
  * 얼마나 많은 지원자들을 면접보고 있는가
  * 원샷 면접인가 다단계 면접인가
  * 지원자에게 어떤 종류의 질문들이 주어지고 있는가
  * 특정된 질문인가 개방형 질문인가
  * 면접관이 기술적 질문에 대해 단답형을 좋아하는가 상세한 생각을 파보려 하는가
* 관리층이 개발자들을 신뢰하는지 확인해보자
* 면접관의 질문들을 분석하면 중요한 정보들을 얻을 수 있을 뿐만 아니라 지원자에게 교육적일 수 있다
* 현실 세계의 문제나 아주 구체적인 상황에 대해서 개방적인 대화를 해보자

**바람직한 면접 방법**

좋은 면접은 자유 토론과도 같아야 한다. 소프트웨어 개발과 관련하여 지식과 정보를 교환하고, 기술/도구/방법론들에 대해서도 의견을 나누어야 한다.

`올바른 집중`

* 무언가 개선하고 싶고, 도입하고 싶은 것들이 있다면 새로 채용될 개발자는 그런 것을 성취하기 위한 지원군이 되어야 한다.

`마인드 맵핑 대화`

* 면접이 끝나면 모든 대화가 마인드 맵으로 종이에 남아 각 지원자와 나누었던 대화들을 다시 기억해내는 데 효과적으로 이용된다.

`페어 프로그래밍 면접`

* 그 어떤 기술 면접도 지원자와의 페어 프로그래밍만큼 좋을 수 없다.
  * 어떤 테스트를 작성할지 얼마나 빨리 결정하는가 / 경험 수준
  * 개발 도구(IDE, 언어, 테스팅/목업 프레임워크, 단축키 등)에 얼마나 익숙한가
  * 클래스, 메서드, 변수 네이밍을 얼마나 적합하게 하는가
  * 코드르 ㄹ얼마나 깨끗하고 명료하게 작성하는가
  * 면접관이 제안이나 조언을 할 때 어떻게 반응하는가
  * 지원자가 어떤 방식으로 생각을 전개하는가
  * 문제 해결만이 아니라 문제 해결을 위한 방법과 과정에도 얼마나 주의를 기울이는가
* 카트는 지원자의 TDD 역량을 시험하거나 일반적인 클린 코드 원칙을 얼마나 지키는지 알아보는 데 좋다.

`개인 컴퓨터를 지참한 면접`

* 지원자가 좋아하는 도구는 무엇인지 알 수 있고, 소중한 면접 시간을 아낄 수 있다.

`맞춤형 면접`

* 스스로에게 다음과 같은 질문을 던져보어야 한다.
  * 우리가 소중히 하는 가치는 무엇인가
  * 동료들로부터 어떤 종류의 태도를 기대하는가
  * 채용하려는 직무의 핵심 스킬은 무엇인가

**번트 홈런**

* 면접을 할 때 특정 기술에 대한 지식이 아니라 지원자의 재능, 태도, 열정 그리고 잠재성을 보아야만 한다.

**기존 팀을 위한 채용, 새로운 팀을 위한 채용**

기존 팀을 위한 채용

* 우리가 일하는 방식과 핵심 가치에 대한 열정과 긍정적인 태도, TDD, 클린 코드, 설계 등에 대한 탄탄한 소프트웨어 개발 기초 역량이 중요

새로운 프로젝트 초기 개발자 채용

* 열정과 소프트웨어 개발 기초 역량 외에도 프로젝트를 제 궤도로 유지하고 성공적으로 이끌어낸 과거 경험, 많은 프로젝트들을 최종 인수 서명 단계까지 고통 속에서 이끌어 본 노련함이 필요

**사전 면접용 코딩 시험**

* 지원자에게 면접 전에 코드를 제출하게 하는 것도 사전 선별을 위한 좋은 방법

**지원자와 회사 모두 면접을 어떻게 하는지 알아야 한다**

* 강한 팀은 각 개발자들 모두 면접을 진행할 수 있어야 한다.
* 모든 개발자들이 팀이 기대하는 인재를 발굴해 낼 수 있어야 한다.

**개발자 채용 면접은 개발자가 보아야 한다**

* 회사는 개발자 채용 면접을 할 때 반드시 개발자로 하여금 면접관 역할을 하도록 해야 한다.

> 면접 과정을 지켜보기만 해도 그 회사와 그 안의 개발팀, 개발자들에 대해 많은 것을 알 수 있다.
>
> 소프트웨어 장인은 상산적인 파트너십과 아침에 일어날 때마다 일하러 가는 것이 행복한 그러한 직장을 찾는다.

## 잘못된 면접 방식

회사의 채용 절차를 하나하나 상세하게 뜯어보면 그 회사가 추구하는 가치와 문화를 엿볼 수 있다.

잘못된 방식

* 똑똑한 척하는 면접관을 세운다
* 수수께끼식 질문을 던진다
* 답을 모르는 질문을 한다
* 지원자를 바보로 만든다
* 인터넷 접속을 막는다
* 종이에 코드를 작성하게 한다
* 알고리즘 문제를 낸다 : 실제 문제에 가까운 과제를 제시해야 한다.
* 전화 면접을 한다

> 개발자들은 회사를 면접하여 평가하고 나쁜 회사들을 걸러낸다.

## 낮은 사기의 대가

개발자들의 낮은 사기는 소프트웨어 프로젝트 실패의 주된 이유 중 하나다.

* 애자일 행오버
* 그저 출퇴근만 하는 개발자들
* 낮은 수준의 동기가 만드는 제약

개발자들에게 열정 불어넣기

* 외부로부터 소프트웨어 장인을 수혈받자
  * 장인은 자신을 둘러싼 사람들에게 영감을 불어 넣기 위해 모든 노력을 아끼지 않는다
  * 항상 다른 여러 개발자들의 멘토로서 행동하는 데 주의를 기울인다
  * 자신의 자기계발 활동을 다른 사람들과 공유하려 한다

> 직원들의 사기가 낮으면 회사가 파괴되기 쉽다.
>
> 개발자에게 동기를 부여할 수 있는 최선의 사람은 바로 동료 (실력있는, 본받고 싶고 영갑을 일으키는)개발자이다.

## 배움의 문화

구성원들이 동기가 부여되어 있지 않거나 자신의 일 자체에 별 관심이 없으면 그 어떤 변화도 효과적으로 일으킬 수 없다

**배움 문화 만들기**

배움의 문화를 만들면 회사에 효율적으로 열정을 주입할 수 있다.

* `북 클럽에 가입하기`: 책을 하나 선택해서 동료들에게 그 책을 읽기 시작할 거라고 공표하자.
* `테크 런치 진행하기`: 팀원들에게 주 1회 정도 점심 시간에 기술 관련 난상 토론회를 갖는 것을 제안해보자.
* `그룹 토론회 참여하기`: 약 5분 동안 주제를 발표하고, 2분의 질답으로 이루어진다. 이후 그룹 토론 주제로 넘어간다.
* `업무 교환하기`: 프로젝트의 한 업무 주기 동안 팀끼리 개발자를 서로 바꾸면 새로운 것을 볼 기회가 생긴다.
  * 기존 결정들에 대한 재검증
  * 지식의 공유
  * 개선
  * 공동 학습
* `얼마 동안만 업무 교환하기`: 몇 시간 내지는 며칠만 팀 간 개발자 교환을 할 수도 있다.
* `그룹 코드 리뷰하기`: 특정 코드 부분이 개선의 여지가 많은지, 모범사례로 공표할 만큼 훌륭한지 동료들간 논쟁하기
  * 주석은 주관적, 개인적으로 표현되어서는 안 된다. 객관적이고 생산적이어야 한다.
  * 누가 코드를 작성하느냐는 중요치 않다.
  * 큰 진전을 이룰 것이라 기대하지 않는다.
* `코딩 실습하기`: 최선의 코드를 작성하는 법 훈련
* `내부 학습 모임 만들기`: 두 사람만 있으면 내부든 외부든 커뮤니티를 시작할 수 있다.
* `회사에서의 펫 프로젝트 시간 허용하기`
* `외부 기술 커뮤니티와 교류하기`: 외부 커뮤니티를 통해 열정적이고 재능있는 수많은 개발자들과 함께 하면 나 자신에게 커다란 도전이 된다.

**배움의 문화를 조성하도록 복돋우기 위한 조언**

* `스스로 모범을 보여라`
* `관심을 보이는 사람들에게 집중하라`
* `강제하지 마라`: 애초의 동기를 꾸준히 유지해야 한다.
* `모두를 변화시키려 들지 말라`
* `모임에 대한 약속을 제때하라`
* `상사의 허락을 구하지 마라`
* `환경과 상황을 투덜대지 마라`
* `리듬을 만들라`

## 기술적 변화의 실행

당신을 둘러싼 것들을 바꾸고 싶다면, 가장 중요한 것은 용기다.

* 동료 개발자, 관리자, 기술 리더와 언성이 높아지는 논쟁을 두려워해서는 안 된다.
  * 단순함을 구추하자.
  * 상대방의 언어로 말하자.
  * 말할 내용에 대해 스스로 제대로 이해하자.
  * 상대방을 존중하자.
  * 경청하는 법을 배우자.
* 주변을 바꾸고 싶다면 `두려움을 버리고`, 인격적으로 못되먹은 사람이 되지 말자.
* 상사를 설득하고 싶다면, 상세사항을 많이 노출하지 말자. 노출할 수록 더 세세한 업무 지시가 돌아올 것이다.
* 지식을 공유하며 `신뢰`를 쌓고, 롤모델이 되어 누군가가 따르고 싶어하고, 조언을 듣고 싶어하는 사람이 되자.
* 권한을 갖고 싶다면, 책임질 수 있는 준비를 해야 한다.

**기술적 변화를 시작하는 방법**

* 지속적으로 품질 좋은 소프트웨어를 딜리버리하며 `신뢰 쌓기`
* 새로운 기술을 제안하기 전에 본인 스스로 충분히 이해하고 `전문성 확보하기`
* 나 스스로 그것을 할 수 있는지 확인해보고 `모범을 보여 사람들 이끌기`
* 의미 있는 곳에 노력을 집중하고, 더 빨리 가치를 얻을 수 있도록 `신중하게 싸울 곳 정하기`
* 큰 충돌을 피하기 위해 `점진적으로 반복, 관찰 수용하기`

## 실용주의 장인정신

**품질은 선택사항이 아니다**

**좋은 품질은 비싸고 시간이 오래 걸린다는말은 잘못된 사실이다**

**리펙토링**

* 레거시 코드를 대상으로 작업할 때는 최소한 수정한 부분만큼은 원래 보다 꺠끗하게 만들어 놓아야 한다.
* 확장에는 열려있고 변경에는 닫힌 OCP 원칙을 준수할 수 있도록 코드를 리펙토링한 후 신규 기능을 추가해보자.

**소프트웨어 개발 방법의 한 가지 예**

* 많이 사용되는 실행 관례들이 절대 불변의 진라라고 믿어서는 안 된다.
* 실행 관례와 절차들은 그보다 더 나은 실행 관례와 절차가 나타나기 전까지만 가치가 있다.
* 여러가지 훌륭한 도구들을 포용하면서 맡은 일의 맥락에 가장 적합한 것을 꺼내어 적용할 수 있어야 한다.

**비즈니스 돕기**

* 개발자들이 비즈니스 담당들과 직접 대화하면서 질문하고 솔루션을 제안할 것을 권장한다.

**소프트웨어 프로젝트는 우리를 위한 것이 아니다**

* 프로젝트를 수행한 사람들이 떠나간 후 그것을 유지보수할 사람들을 고려해야 한다.

**비범함과 평범함**

* 비범한 개발자는 요구사항을 충족하는 가장 단순한 코드를 만들어, 경험이 적은 개발자가 이해하는 데 아무런 문제가 없도록 한다.
  * 단순하고 짧은 솔루션 이상의 것을 추구
  * 가장 훌륭한 코드는 작성할 필요가 없는 코드
  * 잘 작성된 코드는 단순하고, 작고, 테스트 가능하며 이해하기 쉽다.

**단순한 설계를 위한 네 가지 원칙**

Kent Back / J.B Rainsberger

* 모든 테스트를 통과해야 한다. -> 모든 테스트의 통과
* 명료하고, 충분히 표현되고, 일관되어야 한다. -> 중복의 최소화
* 동작이나 설정에 중복이 있어서는 안 된다. -> 명료성의 최대화
* 메서드, 클래스, 모듈의 수는 가능한 적어야 한다. -> 구성요소의 최소화

.

단순한 설계를 위한 가이드 라인

1. (좋은 네이밍, 비즈니스 컨셉을 잘 투영한)추상화에 집중하기
2. 중복을 제거하며 코드의 응집성과 독립성 높이기
3. 새로운 구조가 떠오르면 다시 명료성 높이기
4. 다시 중복 없애기
5. ... (짧은 반복 주기로 작업 완료까지 계속)

**패턴을 위한 리펙토링**

* 새로운 기능을 추가하기 전에 기존 코드를 수정해서 추상화하기
* 당장의 합당한 이유 없이 단지 '미래를 대비해야 한다'는 모호한 전제로 초기부터 추상화를 하면 애플리케이션이 엉망이 된다.
* 실용적인 접근 방법은 실제 필요한 상황이 생겼을 때만 추상화를 도입하는 것.
* 좋아하는 패턴에 문제를 끼워 맞추기 전에, 문제에 적합한 리펙토링을 단순한 설계와 SOLID 원칙을 따라 먼저 시도해보자. 이후 나중에 필요한 상황이 생겼을 때 범용화해보자.

**장인정신과 실용주의**

* 깨끗하고 잘 작성된 코드는 비즈니스의 요구에 맞추어 빠르고 안전하게 변경할 수 있는 기반이 된다.
* 요구사항의 변화에 맞추어 코드를 빠르게 바꿀 수 있는 것이 비즈니스를 돕는 최선의 방법이다.

> 이슈가 되지 않을 정도까지 품질 비용을 낮추기 위해 좋은 실행 관례뜰을 마스터하고 실용주의적인 입장을 취하자.

## 소프트웨어 장인으로서의 커리어

소프트웨어 개발자들은 우리가 살고 있는 세상이 진화해 나가는 데 꼭 필요한 존재다.

**장인의 길**

* 소프트웨어 장인은 소프트웨어 개발과 자신의 직무에 `열정적`이다.
* 다음 세대의 장인을 키우는 데 사회적 윤리적 의무감을 느껴야 한다.
* 항상 최고의 코드를 만들도록 다른 것들을 희생해서라도 계속해서 배우고 남을 도우리라는 각오를 한다.
* 아름다운 코드를 작성하기 위한 일생에 걸친 헌신과 같다.
* 소프트웨어를 통해 가치를 창출할 수 있는 더 나은, 더 효과적인 방법을 찾는 끊임없는 노력의 길이다.
* 새로운 것에 대한 호기심을 가지고 실험한다는 것곽 같다.
* 코드 작성이 아니라 문제 해결에 집중한다.
* 긍정적인 일들로 연상되는 존재여야 한다.

**정직과 용기**

* 고객이 나쁜 의사결정을 할 때 그것이 적절치 못하다고 지적하는 정직함과 용기가 필요하다.
* 모든 '아니오'에는 항상 대안을 제시해야 한다.

**여정과 이정표**

소프트웨어 장인은 스스로의 커리어를 매우 신중하게 계획한다.

* 다음 단계를 위해 앞서 보고, 계획하는 것은 성공적인 커리어를 위해 핵심적이다.
* 일터를 더 나은 곳으로 만드는 데 투자한다는 의미는 우리의 커리어를 더욱 풍요롭게 할 수 있는 기회를 늘린다.

**커리어 만들어 나가기**

일을 선택하기 전에 질문을 스스로에게 던져보자.

면접 과정은 지원자 입장에서도 회사를 평가할 수 있는 기회다. 고용 관계를 맺기 전에 그 기회를 최대한 이용하여 정보를 얻어내자.

* 나의 커리어로부터 나는 무엇을 원하는가?
* 그것을 성취하기 위한 다음 단계는 무엇인가?
* 이 일은 나의 커리어 방향과 합치하는가?
* 내가 이 회사에 줄 수 있는 가치의 양은 얼마나 되는가?
* 그러한 투자에 대한 이익은 무엇인가?
* 그러한 투자는 대략적으로 얼마 동안 지속되어야 하는가?
* 내가 되고자 하는 프로페셔널에 이르는 데 이 일은 어떻게 도움이 되는가?
* 이 일에서 나는 자율성, 통달, 목적의식을 가질 수 있나?
* 나의 고용주와 생산적인 동반자 관계를 맺을 수 있나? 양측 모두 가치를 얻고 행복할 수 있나?

.

* 개인이 커리어 열망과 방향이 합치하는 한 그 회사에 가능한 오랫동안 머무르길 권한다.
* 앞으로 나아가지 못하고 정체되어 있다고 느낀다면, 무언가를 배우거나 스스로 일을 즐기지 못한다면, 그때는 움직여야만 한다.

**원하는 바를 모른다면 어떻게 해야 할까?**

* 내가 원하는 것을 나도 모른다는 것을 인정하자.
* 마음을 열고 사람들을 만나보자.
* 내가 모르던 큰 세상이 있음을 알게 될 것이다.

**다양성**

* 인적 네트워크는 소프트웨어 장인으로서 커리어를 개발해 나가는 데 큰 도움이 된다.
* 다양한 환경을 경험하는 것은 전문화된 장인에 이르는 길에도 도움이 된다.
* 여러 프로젝트, 환경, 회사, 산업, 기술, 소프트웨어적인 문제 접근 방법론을 경험해 나가면서 어떤 분야에 집중할지 방향을 잡아보자.

**소프트웨어 장인의 사명**

* 더 나아지는 데 집중하고, 계속해서 자신의 커리어에 투자하며, 배우고, 가르치고, 공유하기
* 고객에게 항상 가치를 전달할 수 있도록 해야 하고, 프로페셔널리즘, 열정, 관심으로 소프트웨어 산업의 수준을 높이는 것
* 다른 개발자들이 더 나은 코드를 만들고 스스로가 하는 일에 자부심을 갖도록 돕는 데 관심 두기
* 전 세계적으로 소프트웨어 프로젝트들의 품질과 성공 비율을 오늘날보다 높아지도록 하는 것
* 주변의 것들을 더 나아지게 하고 우리가 사는 세상을 변화시킬 것
