Home 15장 훌륭한 프로그래머가 되기 위한 팁과 경험담
Post
Cancel

15장 훌륭한 프로그래머가 되기 위한 팁과 경험담

가치 제안

다양한 기술을 잘 배워두면 자신에게 가치를 더할 수 있다. 경험을 쌓는 방법으로는 가외 프로젝트가 자주 쓰인다. 또 자신의 가치를 높이는 고전적인 방법은 도구를 만드는 것이다.

사람들은 자신에게 필요한 기능이 현재 사용중인 도구에 없다고 생각해서 새 도구를 만들어내곤 한다. 결국 서로 호환되지 않는 방식으로 비슷한 일을 수행하는 수많은 도구가 생겼다. 이런 프로젝트는 가치를 추가하지 않는다. 고로 자기중심적으로 행동해 남에게 민폐끼치는 프로그래머가 되어서는 안 된다. 생태계에 순응하고 대항하지 마라

소프트웨어 개발의 발자취

1) 간추린 역사

유닉스 운영체제 탄생, 첫 번째 이식 가능한 운영체제가 됐다.(여러 종류의 컴퓨터에서 실행 가능)

개인용 PC가 보급되면서 소프트웨어를 작성하는 사람과 컴퓨터를 파는 사람이 구분되기 시작했다. 그리고 빌 게이츠가 등장하면서 경향이 바뀌었다. 게이츠는 금전적 이익에 초점을 맞췄고 우선순위가 산업계에 속한 다른 사람들과는 달랐다. 소프트웨어 개발이 정치가나 변호사에 의해 관리되기 시작하면서 뛰어난 엔지니어링보다는 공정하지 못한 방식에 의해 주도되기 시작했다. 예) MS-DOS는 MS가 개발한 것이 아니라 팀 패터슨이 개발한 운영체제를 산 것이다. MS는 MS-DOS로 돈을 버는 동안 이를 개선하지 않았다.

윈도우가 실행되는 PC가 더 저렴하다는 이유로 PC를 교육에 활용하기 시작했다. 사람들은 자신이 사용하는 시스템의 소스 코드를 볼 수 없었다. 이런 반작용으로 리처드 스톨먼은 GNU 프로젝트를 시작했다. 이것의 목표는 자유롭게 사용가능하고 법적으로 방해받을 걱정이 없는 유닉스 버전을 만드는 것이었다.(오픈소스)

대기업들은 오픈소스 소프트웨어 사용에 회의적이었다. 누가 버그를 고칠까? 이후 오픈소스 소프트웨어를 상업적으로 지원하기 위한 시그너스 서포트가 만들어졌고 이것의 등장으로 회사들이 오픈소스 소프트웨어를 사용하려는 의향이 늘어났다.

2) 오픈소스 소프트웨어

오픈소스 소프트웨어의 주된 장점은 더 많은 사람이 코드를 살펴보기 때문에 안전성이나 신뢰성이 더 높아진다는 점이다. 또 다른 장점은 프로그래머가 모든 것을 완전히 새로 만들지 않고도 다른 사람들이 작업해둔 것을 바탕으로 작업할 수 있다는 점이다. 인터넷과 클라우드 서비스로 인해 오픈소스 소프트웨어 개발은 아주 많이 향상됐다.

하지만 수많은 오픈소스 프로젝트는 학생들의 프로젝트에서 나왔다. 대부분 마무리가 되지 않았거나 문서화가 제대로 되지 않는 등 새로 작성하는 게 편한 경우가 많다. 그래도 다른 사람의 코드를 살펴보면 무엇을 해야할지를 배우는 것만큼 무엇을 하지 말아야 할지도 배울 수 있다. 프로젝트가 한 사람 이상의 기여자에 의해 활발히 개발되고 있다는 사실은 긍정적 지표다.

3) 크리에이티브 커먼즈

4) 이식성의 발전

이식성은 소프트웨어에서 특별한 의미를 지닌다. 이식성 있는 코드는 처음 개발된 환경뿐만 아니라 여러 다양한 환경에서 실행될 수 있다.

5) 패키지 관리

오픈소스 소프트웨어, 특히 리눅스는 소프트웨어 배포 문제를 상당히 악화시켰다. 데스크톱, 안드로이드 폰, 태블릿 등에서 실행되는 여러 가지 설정의 리눅스가 존재한다. 그래서 패키지 관리가 활성화 됐다. 패키지 관리 도구는 프로그램을 의존관계 목록이 포함된 패키지로 묶게 해준다.

6) 컨테이너

컨테이너는 패키지 관리 문제를 해결하는 방법으로 최근에 등장한 새로운 접근 방법이다. 애플리케이션과 모든 의존관계를 컨테이너에 한꺼번에 담는다. 이렇게 담긴 데이터 파일 등의 모든 내용물이 들어 있는 환경에서 프로그램을 실행해주되 시스템의 나머지와는 격리된 상태에서 실행해준다. 그래서 소프트웨어의 deploy(배포)를 단순화해준다.

7) 자바

자바의 새로운 아이디어 중 하나는 모든 대상 기계에 대해 코드를 재컴파일하는 대신 대상 기계에서 실행될 자바 인터프리터만 누군가 재컴파일하면 프로그래머가 자바 코드를 재컴파일할 필요는 없다는 것이다.

교육에 자바가 쓰인 이유 중 하나는 자바가 가비지 컬렉션을 통해 메모리를 관리하기 때문에 초보자에게 복잡한 메모리 관리를 가르치지 않아도 되기 때문이다. 자바의 단점으로는 자바를 중심으로 확장된 프로그래밍 문화를 들 수 있다. 아름다운 클래스 계층을 유지하는 것에 대한 강박관념이 있어서 때로 어떤 목표를 달성하는 것보다 클래스 계층 유지에 더 우선순위를 두곤 한다.

좋은 예로 자바 데이터베이스 도구인 하이버네이트를 들 수 있다. 하이버네이트는 자바 클래스와 하위 클래스로 데이터 은닉의 목표를 달성하려 한다. 또 HQL(하이버네이트 질의 언어)라는 추상화를 일반적으로 SQL인 기반 데이터베이스 API 위에 제공하는 것이다.

8) 노드제이에스 (Nodejs)

Node.js는 자바스크립트가 브라우저 밖에서 실행되게 해주는 최근에 나온 환경이다. 가장 큰 매력은 클라이언트와 서버 쪽 애플리케이션을 하나의 프로그래밍 언어로 작성할 수 있다는 점이다.

단점으로

  1. 노드는 자신만의 패키지 관리자를 만들었다. 사람들에게 필요하지만 호환되지 않는 방법으로 만들었기 때문에 시스템을 유지보수하기 더 어려워졌다.
  2. 의존성이 꼬인 노드 패키지가 수천가지가 있고 상당수는 심각한 작업에 적당하지 않다.

9) 클라우드 컴퓨팅

클라우드 컴퓨팅은 네트워크를 통해 다른 누군가의 컴퓨터를 쓴다는 뜻이다. 클라우드 컴퓨팅은 컴퓨팅 자원을 빌려준다는 새로운 비즈니스 모델을 만들었다.

10) 가상머신

과거에는 프로그램이 한 컴퓨터에서 하나씩만 실행됐다. 운영체제는 시분할을 통해 여러 프로그램을 실행할 수 있게 해준다.

운영체제가 물리적 기계 하드웨어 위에서 바로 실행될 필요가 없으므로 이런 시스템을 가상 머신이라고 부른다. 가상 머신은 특정 운영체제에 종속되는 것을 방지한다는 면 외에도 여러 가지 장점을 제공한다.

가상 머신은 클라우드 컴퓨팅 세계의 주류다. 클라우드상에서 공간을 빌리고 원하는 운영체제를 조합해 실행할 수 있다. 가상 머신을 운영하는 시스템을 하이퍼바이저라고 부르기도 한다.

11) 이동식 장치

프로그래밍 환경

1) 초보 프로그래머도 경험을 얻는 방법

어떻게 하면 필요한 기술을 갖출 수 있을까? 어떻게 해야 경험을 잘 정의할 수 있을까? 무엇보다 기본이 탄탄해야 한다. 경험은 무엇을 할 수 있고 무엇을 할 수 없는지를 아는 것이다. 해보지도 않은 일을 할 수 있을지 어떻게 알 수 있을까? 추정을 통해 배울 수 있다. 추정은 단순한 추측이 아니라 경험을 바탕으로 하는 직관적인 어림짐작이다.

2) 추정하는 방법 배우기

팀원으로써 가장 파괴적인 행위는 아무 경고도 없이 결과물을 제때 전달하지 않는 것이다. 어떻게 하면 추정을 할 수 있을까? 연습을 통해 추정하는 방법을 배울 수 있다. 숙제등의 작업을 시작하기 전 그 작업이 얼마나 걸릴지 추정한 값을 적어두고 그 후 실제 작업이 얼마나 걸렸는지 추적해보자 이런 연습을 통해 추정이 나아지고 있음을 발견하게 된다.

3) 프로젝트 스케줄링

4) 의사결정

5) 성향이 다른 사람들과 함께 일하기

6) 직장 내 문화 다루기

사람들은 직업에서 금전적 보상을 받고, 경력에서 향상을 원하며 소명에서 즐거움을 얻는다. 이런 성격 분류에 따라 직접이나 경력에 주안을 두는 사람은 사람 중심 문화에서 더 잘 일할 수 있고, 이는 원만한 개인 관계라는 보상을 제공한다.

소명과 결과 중심 문화는 서로 잘 어울리고 최선의 결과를 이룰 수만 있다면 그 과정에서 불꽃튀는 설전이 오가고 강렬한 비판이 이뤄져도 사람들이 만족스러워 한다.

7) 정보를 얻은 상태에서 선택하기

개발 방법론

노력이 이뤄지는 모든 분야는 결국 방법론 전문가를 양산하는 것 같다. 프로그래밍도 다르지 않다. 다만 방법론이라고 부르는 것보다 이데올로기라고 부르는 편이 더 어울릴법한 열혈분자가 있다는 점이 다르다.

이데올로기와 방법론 사이의 차이는 사용자의 역할에 있다. 실패 비용이 높은 경우에는 어떤 일을 해야 할지 정확히 아는 것이 중요하다. 실패 비용이 낮은 경우에는 명확한 정의를 미리 작성해야 할 인센티브가 상대적으로 작아진다. 그래서 만들어서 봐야 우리가 원하는 건지 알 수 있어 라는 접근 방법을 더 많이 선택한다.

프로젝트 설계

1) 생각을 글로 써보자

아이디어를 글로 써보자 문서를 올바른 수준까지 작성하는 것이 중요하다. 일을 처리할 방법을 적지 말고 하고 싶은 일을 적어야 한다.

2) 빠른 프로토타이핑

빠른 프로토타이핑은 부분적으로 작동하는 프로젝트 결과물을 사람들에게 내보이는 것이 포함된 것으로 문서를 작성하는 것처럼 프로토타이핑도 아이디어를 더 깊이 이해하는 데 도움이 된다.

주의사항

  1. 프로토타입을 프로덕션 코드와 혼동하지 마라
  2. 억지로 프로토타입 작성에 빡빡한 스케줄을 부여하지 않게 하라
  3. 관리자가 프로토타입을 외부에 배포할 수 있는 제품으로 착각하지 않도록 주의하라

프로토타입 코드를 외부로 배포할 경우 드러나는 전형적인 특징은 응집도가 떨어진다는 점이다. 프로토타이핑은 주로 블록을 가지고 작업한다. 프로토타입의 동작을 관장하는 원칙을 관찰하고 이런 원칙을 일관성 있게 적용하면서 새로 코드를 재구현해야 한다.

3) 인터페이스 설계

우리의 프로젝트는 소프트웨어 스택에서 어느 위치를 차지하고 있을 것이다. 소프트웨어는 샌트위치의 속처럼 자기 위아래와 통신하며 스택안에 존재한다. 애플리케이션의 인터페이스는 샌드위치의 아래쪽 빵을 사용해 결정되므로 위쪽 인터페이스를 결정해야 한다.

시스템 프로그래밍은 하드웨어와 애플리케이션 사이에 위치한다. 소프트웨어 스택에서 한 스택과 다른 스택 사이의 선을 애플리케이션 프로그램 인터페이스(API)라고 부른다. API가 프로그램이 아닌 사람을 대상으로 하면 사용자 인터페이스(UI)라고 부른다.

[API 설계]

  1. API는 자세한 내부 구현을 노출해서는 안 되고, 특정 구현에 의존해서도 안 된다.
  2. API는 응집도가 높아야 한다. (좋은 추상화를 제공해야 한다)
  3. API는 확장 가능해야 한다.
  4. API는 최소화해야 한다.(같은 일을 처리하는 방법을 여러 가지로 제공하지 말아야한다.)
  5. 모듈화가 잘 되어 있으면 좋다. API가 연관된 기능을 제공한다면 이들을 가능한한 서로 독립적으로 만들어라
  6. 기능은 합성 가능해야 한다.(조합하기 쉬워야 한다)

4) 코드를 재활용 할 것인가, 직접 작성할 것인가

보통 라이브러리가 차지하는 메모리 크기가 직접 작성한 코드가 차지하는 메모리 크기보다 크면 라이브러리를 쓰지 말라고 말한다.

프로젝트 개발

2) 이식성이 있는 코드

3) 소스 코드 제어

프로그램은 바뀐다. 기능 추가나 버그 수정을 위해 변경하는 등의 일이 자주 벌어진다. 따라서 새로운 버전에 버그를 수정한 경우 어떤 부분이 변경됐는지 확인해야 하기 때문에 소스 코드를 과거로 돌릴 수 있는게 아주 중요하다.

두 파일을 비교해서 달라진 부분의 목록을 생성해내는 diff라는 프로그램이 있다. 이 프로그램의 옵션 중 출력을 텍스트 편집기 파이프로 연결해 넣으면 변경 목록을 활용해 한 파일을 변경된 파일로 바꿔주는 기능이 있었다. 이런 diff의 아이디어를 바탕으로 소스 코드 제어 시스템(SCCS) 을 만들었다.

SCCS는 파일이 바뀌면 원본과 각 버전의 변경 목록을 저장했다. 그리고 사용자가 어떤 버전의 파일을 요구하면 원본에 모든 변경 버전을 적용해서 그 자리에서 만든 원하는 버전의 파일을 얻을 수 있었다.

SCCS의 단점을 보안한 변경 제어 시스템(RCS)가 나왔고 RCS는 더 나은 사용자 인터페이스를 제공하고 후방 변경 이력을 사용함으로써 가장 최신 버전을 저장하고 최신 버전으로부터 옛 버전을 만들어 냈다. 따라서 속도도 빨라졌다.

이후 동시성 버전 제어 시스템(CVS)는 RCS와 비슷한 기능을 네트워크로 접근할 수 있게 해주면서 최초로 파일 잠금 대신 병합을 사용한 시스템이다.

이후 serversion, Git, 등의 분산 시스템이 만들어졌다.

4) 테스트

테스트를 하지 않으면 프로그램이 잘 작동하는지 실제로 알 수가 없다. 프로그램을 작성할 때 테스트 집합도 만들어야 한다.

5) 버그 보고와 추적

6) 리팩토링

리팩토링은 코드의 인터페이스나 동작은 바꾸지 않고 코드 내부를 재작성해 개선하는 과정을 말한다. 리팩토링을 하는 이유는 코드가 완전히 구체화되면 지저분해지거나 좀 더 낫게 문제를 처리하는 방법을 알게 되는 경우가 있기 때문이다. 리팩토링을 하면 유지보수 비용을 줄일 수 있다. 하지만 리팩토링 전과 후가 똑같이 작동한다는 사실을 확인하려면 좋은 테스트 집합이 필요하다.

**리팩토링 과정중 새로운 기능을 추가하고 싶은 욕구가 느껴지더라도 절대 그 기능을 집어 넣지 마라!

7) 유지보수

진지한 코드의 경우 개발에 드는 비용보다 유지보수에 드는 비용이 훨씬 더 크다. 동료들이 감탄할 만큼 멋지게 비틀어 작성한 코드는 피하자 유지보수 하는 사람이 똑똑하지 못하면 코드를 보고 유지보수를 하는 것이 아니라 코드를 새로 설계하게 된다.

스타일을 지켜라

소프트웨어는 깔끔하게 작성하고 문서도 잘 작성하자 코드에서 벌어지는 일을 다른 사람이 잘 이해할 수 있게 하지 않으면 아무도 나를 도와줄 수 없다.

기존 프로젝트를 활용하라

This post is licensed under CC BY 4.0 by the author.

14장 세상을 바꾸는 기계 지능

1장 인프라 아키텍처를 살펴보자