본문 바로가기
SW

커리어 스킬 - 3부 : 소프트웨어 개발에 대해 알아야 할 것 (30 ~ 35장) (The Complete Software Developer's Career Guide)

by 라꾸스떼(YR) 2019. 12. 22.
반응형

[30장] 소스 제어

[소스 제어란 무엇인가?]

소스 코드를 기록 관리 및 추적하는 방법으로 개발자라면 필수적으로 신경써야한다.

 

[소스 제어가 중요한 이유는 무엇인가?]

유지보수 및 관리를 위해서는 필수다. 그리고 다들 경험해본적 있지는 않을까 싶다.. 코드를 몽땅 날려먹는 일이라던지...

더욱이 협업을 하기 위해서는 반드시 소스 제어가 되어야만 하다.

 

[소스 제어의 기본]

-

 

[저장소(Repository)]

코드를 저장해두는 장소.

 

[코드 체크아웃]

저장소에서 본인이 작업하고 있는 로컬로 코드를 가져온다는 의미이다. 반대는 '체크인'.

 

[리비전]

소스 제어에 저장된 파일의 이전 버전을 가리키는 리비전.

리비전 관리를 잘하려면 주석을 잘 써놔야 한다...!

 

[분기(branch)]

대부분의 소스 제어 시스템은 기존의 코드 베이스에서 브랜치를 만들어 트렁크로부터 독립적으로 진화한 새로운 코드 베이스를 만들 수 있게 해준다. <p375>

 

[병합]

-

 

[충돌]

-

 

[기술]

-

 

[중앙 집중형 소스 제어]

중앙 서버에 한 개의 저장소가 있다.

<업무 흐름>

1. 작업 중인 코드의 로컬 사본을 저장소로부터 업데이트하기.

2. 수정하기.

3.중앙 저장소에 수정 사항 커밋하기.

 

[분산 제어형 소스 제어]

각 개발자가 자신이 컴퓨터에 전체 저장소의 완전한 사본을 가지고 있다. 프로젝트의 저장 시스템 역할을 하는 저장소 중앙 버전 혹은 마스터 저장소는 있어야 한다.

 

[가장 인기 있는 소스 제어 시스템에 대한 간단한 소개]

-

 

[CVS]

-

 

[Subversion]

-

 

[Git]

-

 

[Mercurial]

-

 

[그 밖에 다른 건 없나요?]

"미리 커밋하고 자주 커밋하라. 그리고 부탁하건대 커밋 메시지 좀 제대로 작성하자."

그리고 제발 병합 후에 테스트하고 푸쉬하자...

 

[31장] 지속적 통합

'소프트웨어를 빌드하고 이를 배포하기 위해 테스트하고 패키징하는 과정은 느리고 고통스럽고 따분한 데다 에러도 많이 난다. 그런데 지속적 통합은(continuous integration) 이 과정을 자동화해준다. 병합 지옥에 빠지지 않게 막아준다. 빠른 피드백을 제공한다. 피드백 주기가 빠를수록 소프트웨어의 진화는 빨라지고 전체 품질은 더 많이 개선된다. 이는 애자일 개발에서 매우 중요한 요소다.'

 

[과거의 코드 빌드 방법]

-

 

[그리고 빌드 서버가 등장한다]

'환경과 라이브러리를 제대로 갖춘 중앙 빌드 서버 - 주간빌드/야간빌드. 야간 빌드란 매일 밤 빌드 서버가 새로운 빌드를 만들어서 코드를 통합하는 것이다. 중앙 빌드 서버를 사용하는 야간 빌드 덕에 모두가 동기화될 수 있었다. 그 대신 야간 빌드에 문제가 생기면 그 문제부터 해결해야 했다.

Makefile 스크립트는 빌드 서버에서 빌드 프로세스 전체를 처리할 수 있을 정도로 정교해지기 시작했고 앤트(Ant)같은 XML기반의 빌드 자동화 도구가 등장했다.'

Makefile 작성 방법은 알아둘 필요가 있다.

 

[마침내 지속적 통합으로]

'어떻게 해야 새 코드를 소스 제어에 체크인할 때마다 코드를 빌드할 수 있을까? 답은 지속적 통합 서버였다. 지속적 통합은 처음 한 번만 체크인해두면 단위 테스트, 정적 코드 분석기 같은 코드 품질 평가 실행이 동시에 이루어지는 수준까지 진화했다. 피드백 주기가 짧아지도록 개발자들이 코드를 최대한 빨리 자주 체크인하게 하는 부분이 가장 어려웠다. 실패한 단위 테스트를 알아내고 문제가 된 변경 사항을 찾기 위해 회귀 테스트도 자동 실행할 수 있게 되었다.'

이런 과정을 매번 수동으로 하고 있는데... 이 지옥의 고리를 끊기 위해 CI 도입을 서둘러야 겠다.

 

[지속적 통합 작업 흐름 샘플]

<코드 체크인>

<새 빌드 시작>

<코드 체크아웃>

<정적 분석기 실행> : 코드 품질을 측정

<단위 테스트 실행>

<결과 보고>

<소프트웨어 패키징>

<코드의 선택적 배포(지속적 배포)>

<완료>

 

[CI 서버와 소프트웨어]

-

 

[32장] 디버깅

'디버깅에 접근하는 태도가 무엇보다 중요하다는 걸 깨달아야 한다. 문제에 체계적으로 접근하라. 서두르지 마라. 문제를 바로 찾을 수 있을 거라 기대하고 시작했다가 쉽게 포기하지도 말아라. 차분하고 침착한 태도를 유지하라. 감정적인 태도를 버리고 논리적이고 분석적인 태도로 문제를 공략하라.'

저자의 말이 옳다. 디버깅은 끈기의 문제라고 생각한다. 바로 해결할 버그였으면 코드 작성하다가 바로 해결했을 경우가 크다.

 

[디버깅이란 무엇인가?]

코드 베이스에서 문제의 근원을 찾아서 그 문제를 일으킬 만한 요인을 가려내고, 여러 가설을 시험해보는 과정을 통해 뿌리가 되는 진정한 원인을 찾고 그 원인을 제거한 후, 다시는 그 문제가 일어나지 않도록 하는 것이 디버깅이다. <p397>

 

[디버깅 첫 번째 규칙: 디버거를 쓰지 마라]

코드에 디버그할 문제가 생기면 프로그래머들은 늘 쓰는 디버거를 켜고 버그를 찾는데 돌입한다. 틀렸다. 그렇게 하지 마라. 디버거는 최후의 수단으로 남겨둬야 한다. <p398>

 

[에러를 재현하라]

버그를 재현해서 진짜 버그가 발생한 게 맞는 확인부터 한다. 100퍼센트 재현할 수 없는 문제는 디버깅할 수 없다. 재현할 수 없는 문제는 디버깅하는 게 의미가 없다. 디버깅하기 전에 버그부터 재현하라. 버그가 간헐적으로 발생해서 확실하게 재현하는 게 불가능할 때는 재현에 필요한 환경이 무엇인지 모른다는 뜻이다. 문제라면 재현할 수 있어야 한다. 재현할 방법을 반드시 알아내야 한다. <p399>

 

[앉아서 생각하라]

앉아서 생각하라. 어디를 살펴보고 무엇을 찾을지부터 아는게 중요하다. 정말 아무 생각도 나지 않아서 디버거를 켜고 싶은 충동을 느낀다면 그 대신 소스 코드를 훑어보라. 2~3가지 쓸 만한 가설은 생각해내야 한다. <p400>

 

[가설을 테스트하라]

자신이 세운 가설을 테스트할 단위 테스트를 작성하라. 추측이 틀려서 다누이 테스트에 단언문을 제대로 작성해 두었는데도 만들어둔 단위 테스트를 문제없이 통과했다면, 프로젝트에 단위 테스트가 추가된 덕에 시스템이 더 튼튼해졌고 가설 중 하나가 틀렸다는 걸 입증했다고 생각하라. 문제를 좁혀가는 과정이라고 생각하라. 단위 테스트를 작성하고 하나씩 통과할 때마다 가능성을 제거하는 것이다. 무조건 통과하는 단위 테스트를 만들지 않게 주의하라. <p401>

 

[가정을 확인하라]

디버거 사용은 최소로 줄여라. 꼭 써야 한다면 이미 세운 특정한 가정이 유효한지 확인하는 용도로만 활용하라. <p402>

 

[분할 정복하라]

디버깅이 잘 안 풀릴 때, 때로는 문제를 반으로 자를 방법을 찾아보는 것도 좋다. <p404>

 

[고칠 때는 이유를 이해하라]

문제를 고칠 때는 자신이 한 행위가 어떻게 그 문제를 고쳤는지 이해해야 한다. 그 문제가 왜 고쳐졌는지 이해하지 못하면 아직 문제를 다 고친 게 아니다. 문제가 저절로 사라지는 일은 없다. 무엇이 망가졌고 왜 어떻게 고쳤는지 이해해야 할 뿐 아니라 고쳤다는 걸 확인하는 절차도 반드시 거쳐야 한다. 사실 고쳤는지만 확인하지 말고 회귀 테스트를 작성해서 그런 일이 다시 발생하지 않게 하는 게 좋다. 마지막으로 버그가 발생한 클래스의 다른 인스턴스를 살펴보라. 버그는 서로 붙어 다니는 경향이 있다. <p404>

 

[예술과 과학]

-

 

[33장] 코드 유지 보수

막상 개발자가 되면 새 코드를 쓰는 시간보다 코드를 유지 보수하는 시간이 훨씬 더 길다.

코드를 적절히 유지 보수하는 방법을 알아야 한다. 프로그램은 잘 유지 보수해주지 않으면 시간이 갈수록 점점 망가지다가 결국 완전히 무너져버릴 것이다.

유지 보수하기 쉽게 코드를 작성하는 방버도 알아야 한다. 이 방법을 모르고 마구잡이로 프로그램을 만들면 나중에 당신이 작성한 코드를 유지 보수하던 사람이 밤중에 집으로 찾아와 잠든 당신을 죽이려 들 수도 있다. <p407>

 

[당신은 코드를 유지 보수하는 데 대부분의 시간을 보내게 될 것이다]

세상에는 새로운 소프트웨어의 수보다 오래된 소프트웨어의 수가 항상 더 많을 것이다. 오래된 소프트웨어는 끊임없이 개선하고 유지 보수해야 한다. 고객은 고쳐야 할 버그를 계속 찾아낸다. 신기능은 추가하고 기존 기능은 수정해야 한다. 소프트웨어 제품은 살아 숨 쉬는 유기체와 같다. 끊임없이 성장하고 바뀌며 천천히 죽어간다. <p408>

 

[훌륭한 개발자는 유지 보수하기 좋은 코드를 만든다]

1. 자신이 작성한 코드가 유지 보수 단계에 가장 오랜 시간 머무를 것을 안다.

2. 버려지거나 재작성되지 않고 오래 살아남는 코드가 가치 있는 코드라는 걸 안다.

3. 이해가 잘 되고 수정하거나 유지 보수하기 쉬운 명확하고 좋은 코드를 작성한다.

4. 느슨하게 결합된 유연한 설계를 선호한다. 그래야 수정 사항이 생겨도 시스템의 다른 컴포넌트에 영향을 주지 않기 때문이다.

5. 따로 설명이 없어도 이해하기 쉬운 코드를 만든다. 문서화 작업도 특별히 신경 쓴다.

 

[보이 스카우트 규칙]

캠핑한 장소를 자신이 처음 왔을 때보다 더 깨끗하게 만들어 두고 떠나라. <p410>

1. 버그 수정, 새 기능 추가 등의 작업을 할 때 자신이 받은 것보다 약간 더 나은 코드가 되게 만들어라.

2. 단위 테스트를 추가하여 내 뒤에 코드를 받아서 뭔가를 바꾸어야 할 개발자에게 좀 더 튼튼한 코드를 만들어줘라.

3. 변수 이름을 바꿔 코드의 의미를 조금 더 명확하게 보여줘라.

4. 몇몇 기능을 메서드나 프로시저로 그룹화하여 불필요한 부분을 빼고 이해도를 높여라.

5. 많은 코드를 리팩토링하여 더 깔끔하고 단순하게 설계하라.

 

[가독성이 가장 중요하다]

코드를 유지 보수하기 쉽게 만드는 데 가장 큰 영향을 미치는 요소는 가독성이다. 간결한 것도 좋지만 너무 짧고 기발한 코드는 재앙으로 이어지기 십상이다. 왜냐하면 코드를 작성한 시간보다 읽는 시간이 훨씬 더 길기 때문이다. 알아보기 쉬운 코드가 유지 보수하기 쉽다. <p411>

 

[코드 리팩토링]

리팩토링은 기존 코드 설계를 개선하는 과정이다. 기존 코드의 기능은 그대로 두고 조금 더 가독성을 높이는 것. 코드가 바뀌면 단위 테스트 코드도 반드시 바꾸어야 한다. <p412>

 

[자동화는 필수다]

수정한 내용을 빠르게 테스트할 수 있다는 건 더 튼튼한 안전망을 보유하는 것이나 다름없다. 그러면 기존 코드 베이스에 새로운 버그나 에러가 발생하는 것을 막는 데에도 도움이 된다. 자동 빌드, 지속적 통합 시스템, 자동 테스트를 갖추면 코드를 간편하게 수정하고 고장 난 부분을 빠르게 찾을 수 있다. <p413>

 

[주석을 쓸 거라면 잘 써라]

주석이 없어도 이해할 수 있는 명확하고 표현력이 좋은 코드를 쓰는 게 주석을 읽어야만 이해할 수 있는 모호한 코드를 쓰는 것보다 좋다.

주석을 쓸 거라면 꼭 제대로 쓰기를 바란다. 수수께끼 같은 주석은 수수께끼 같은 코드만큼 나쁘다. 커밋 메시지도 최대한 알아보기 쉽고 도움이 되게 써라. <p414>

 

[유지 보수하기 쉬운 코드 쓰는 법을 배울 수 있는 자료]

clean code, code complete, working effectively with legacy code, refactoring.

완벽을 기하는 것보다 통일성을 이루는 게 우선이다. <p416>

 

[34장] 직업과 직함

[직함은 그리 중요하지 않다]

-

 

[하지만 최대한 좋은 직함을 구하라]

-

 

[흔히 쓰는 명칭]

-

 

[피해야 할 직함]

-

 

[기본적인 직함 혹은 직급]

-

 

[기술 관련 대형 회사의 직함]

-

 

[직함에 대한 이야기는 이 정도다]

-

 

[35장] 업무 유형

[코드 작성하기]

일반적으로 회사가 작을수록 코딩하는 시간이 더 길어진다. 회사가 커지면 부수적으로 해야 할 일이 늘어나서 코딩할 수 있는 시간이 줄어든다. 사는 게 원래 그렇다. <p427>

 

[버그 고치기]

가끔 새 코드를 작성할 때도 있지만, 오래된 코드의 버그부터 고쳐야 한다. <p427>

 

[설계와 아키텍처]

훌륭한 소프트웨어 개발자치고 바로 코딩부터 하는 사람은 많지 않다. 그들은 코딩에 돌입하기 전에 어떻게 코딩할지 설계하고, 왜 이 방식이 다른 방식보다 0.01퍼센트 더 나은지 주변에 있는 다른 개발자와 논쟁하는 일부터 한다. <p428>

 

[회의]

스크럼 같은 프로세스를 따를 때는 계획 회의에 참석해서 해당 스프린트 동안 할 일을 계획하는 과정이 꼭 필요하다. 회고 회의나 리뷰 회의도 일한 내용을 보여주고 피드백을 받고 업무를 개선해나가는 데 도움이 된다. 프로젝트 수준의 중요한 결정을 내려야 할 때는 기술적인 내용을 이해하고 있는 개발자가 참석해야만 올바른 결정을 내릴 수 있다. <p429>

 

[학습]

직장에서도 해야 하고 자유 시간에도 해야 한다. 꾸준히 학습하지 않으면서 좋은 소프트웨어 개발자가 된다는 건 어불성설이다. 그러므로 공부하자. <p429>

 

[실험과 탐색]

맡은 업무를 효과적으로 하려면 코드 베이스에 있는 기존의 코드를 읽는 데 많은 시간을 들여야 한다. <p430>

 

[테스트]

테스트는 소프트웨어 개발의 필수 요소다. 훌륭한 소프트웨어 개발자라면 자신의 코드를 체크인하고 배포하기 전에 반드시 테스트한다.

소프트웨어 개발자라면 자신이 작성한 코드의 품질을 책임져야 한다. <p431>

 

[생각하기]

코딩에 돌입하기 전에 코드를 어떻게 작성할지 적어도 세 번 이상 생각해볼 시간을 갖는 게 좋다. 해결 방법에 대한 고민을 미리 잘 해두면 코드를 다시 쓰고 디버깅하는 시간이 줄어든다. 공책을 꺼내서 자신이 생각한 해결책을 직접 적어보는 것도 좋다. 그러면 자신이 무언가 생각했다는 걸 보여줄 물리적 증거가 생긴다. 특정 작업을 어떤 방식으로 하기로 결정했는데 그 이유가 뭐였는지 기억 나지 않을 때 확인할 자료도 된다. <p432>

 

[고객/이해 당사자와 소통하기]

'인간관계론'

자신이 만드는 시스템의 요구 사항을 잘 이해해야만 좋은 개발자가 될 수 있다. <p433>

 

[교육/멘토링]

-

 

[여기까지다…]

-

반응형

댓글