-
실용주의 프로그래머 7장 - 코딩하는 동안Book Study 2024. 2. 20. 20:28
나의 키워드
- 파충류의 뇌에 귀 기울이기
- 우연에 맡기는 프로그래밍
- 알고리즘의 속도
- 리팩터링
- 일단 코딩에 들어가면 대부분 기계적인 작업, 즉 설계 내용을 컴퓨터가 실행할 수 있는 문장으로 바꾸는 일만 하면 된다고들 많이 생각한다. 이런 태도가 소프트웨어 프로젝트가 실패하는 가장 큰 원인이다. 이런 태도 때문에 많은 시스템이 결국 너저분해지고, 비효율적이 되고, 구조가 망가지고, 유지 보수가 힘들어지고, 한마디로 완전히 잘못되고 만다. (p.273)
- 적극적으로 자기 코드에 대해 생각하지 않는 프로그래머는 우연에 맡기는 프로그래밍을 하는 것이다. 코드가 작동하긴 하지만 왜 그렇게 작동하는지 설명은 못한다. (p.274)
- 테스트는 버그를 찾는 작업이 아니다. 여러분의 코드에 대한 피드백을 받는 작업이다.
파충류의 뇌에 귀 기울이기
오직 인간만이 무언가를 직접 보고, 정확한 예측에 필요한 모든 정보를 획득하고, 심지어 순간적으로는 정확한 예측을 한 후에도, 그런데 그것이 아니라고 말할 수 있다. - 개빈 드 베커, 서늘한 신호
- 본능이란 우리 뇌의 무의식 속에 채워져 있는 패턴에 대한 단순한 반응이다. 일부는 선천적이고, 나머지는 반복을 통해 습득한다. (p.276)
- 어디에서 왔는지에 상관없이 모든 본능에는 공통점이 있다. 바로 말로 표현할 수 없다는 것, 생각이 아니라 느낌이라는 점이다. 본능이 반응한다고 머리 위에 반짝이는 전구가 나타나지는 않는다. 오히려 그저 불안하고 초조해지기만 한다. (p.276)
- 누구나 텅 빈 화면을 두려워한다. 아무것도 없는 가운데 외로이 깜빡이는 커서를 떠올려 보라. 새로운 프로젝트를 시작하는 일도 두렵기는 마찬가지다. 우리 생각에 이런 문제에는 두 가지 원인이 있다. (p.277)
- 첫 번째 원인은 파충류의 뇌가 여러분에게 무언가 할 말이 있어서다. 여러분은 개발자로서 여러 가지를 시도해 보면서 잘 되는 것과 안 되는 것들을 보아 왔다. 경험과 지혜를 축적해 온 것이다. 어떤 것이 문제라고 정확하게 짚지는 못하더라도, 시간을 좀 주면 여러분의 의심은 아마도 좀 더 실체가 있고 대응책을 생각할 수 있는 무엇으로 구체화될 것이다.
- 두 번째 이유는 조금 더 진부한데, 여러분은 그저 실수할까 봐 두려운 것일 수 있다.
- 여러분의 본능, 여러분의 무의식, 파충류의 뇌에게 귀 기울이고 또 기울이기 바란다. (p.278)
- 그리고 수년 만에 우리는 괜찮은 자기기만 방법을 찾아냈다. 바로 무언가를 프로토타이핑해야 한다고 자신에게 말하는 것이다. 빈 스크린을 마주하고 있다면 프로젝트에서 시도해 보고 싶은 특정한 측면을 찾아보라.
- 포스트잇에 “프로토타이핑 중”이라고 써서 모니터 옆에 붙여라
- 프로토타이핑은 원래 실패한다고 자신에게 상기시켜라.
- 텅 빈 에디터 화면에 여러분이 배우고 싶은 것 혹은 하고 싶은 것을 한 문장의 주석으로 표현해 보라
- 코딩을 시작하라
- 의심이 들기 시작하면 포스트잇을 보라 (p.228)
우연에 맡기는 프로그래밍
- 우리는 우연에 맡기는 프로그래밍, 곧 행운과 우연한 성공에 의존하는 프로그래밍을 하지 않아야 한다. 대신 ‘의도적으로 프로그래밍’해야 한다. (p.282)
- 왜 코드가 망가졌는지 프레드가 모르는 까닭은 애초에 코드가 왜 잘 돌아가는지도 몰랐기 때문이다. (p.283)
- 제한적으로 ‘테스트’를 했을 때는 코드가 잘 돌아가는 것처럼 보였지만, 그것은 단지 그때 운이 좋았을 뿐이다. (p.283)
- 단순히 코드가 지금 작성된 방식이 그렇기 때문에 생기는 우연한 일들이 있다. 이런 우연에 기대다 보면 결국 문서화되지 않은 에러나 예외적인 경우의 동작에 의존하게 되고 만다. (p.283)
- “이제 돌아는 가니까, 그대로 놔두는 편이 더 나을 거야…” (p.284)
- 우연은 여러 단계에서 우리를 오도할 수 있다. 요구 사항을 만들어내는 단계부터 테스팅에 이르기까지 이 모든 단계에서 말이다. 가정하지 말라. 증명하라. (p.287)
- 모든 차원에서 사람들은 마음속에 많은 가정을 품고 작업한다. 하지만 이런 가정을 문서화하는 경우는 드물며 개발자마다 가정이 다를 때도 많다. (p.287)
- 의도적으로 프로그래밍하라. (p.288)
- 언제나 여러분이 지금 무엇을 하고 있는지 알아야 한다
- 자신도 잘 모르는 코드를 만들지 말라
- 계획을 세우고 그것을 바탕으로 진행하라
- 신뢰할 수 있는 것에만 기대라
- 가정을 기록으로 남겨라
- 코드뿐 아니라 여러분이 세운 가정도 테스트해 보아야 한다
- 노력을 기울일 대상의 우선순위를 정하라
- 과거의 노예가 되지 말라
알고리즘의 속도
- 실용주의 프로그래머가 거의 날마다 하는 또 다른 종류의 추정이 있다. 바로 알고리즘이 사용하는 자원, 곧 시간, 프로세서, 메모리 등을 추정하는 것이다. (p.291)
- 일반적으로 입력의 크기는 알고리즘에 영향을 준다. 입력의 크기가 클수록 알고리즘의 수행 시간이 길어지거나 사용하는 메모리 양이 늘어난다. (p.291)
- 이런 관계가 늘 1차 함수처럼 선형적이라면, 다시 말해 늘어나는 시간이 n에 정비례한다면 이 항목은 그다지 중요하지 않을 것이다. 하지만 중요한 알고리즘은 대부분 선형적이지 않다. (p.291)
- 좋은 소식은 많은 알고리즘의 증가 폭이 선형보다 작다는 것이지만, 나쁜 소식은 나머지 알고리즘들은 증가 폭이 선형보다 훨씬 클 수 있다. 즉 수행 시간이나 메모리 요구량이 n보다 훨씬 빠르게 늘어난다. (p.292)
- 대문자 O 표기법은 수행 시간이든 메모리든, 아니면 다른 무엇을 나타내는 실제 숫자를 알려주지 않는다. 그저 입력의 크기가 바뀜에 따라 이 값이 어떻게 바뀔지를 알려줄 뿐이다. (p.293)
-
O(1) 상수 (배열의 원소 접근, 단순 명령문) O(log n) 로그 (이진 검색) 로그의 밑은 중요치 않다. O(n) 선형 (순차 검색) O(n log n) 퀵 정렬과 힙 정렬의 평균 수행 시간 O(n^2) 제곱 (선택 정렬과 삽입 정렬) O(n^3) 세제곱 (두 n * n 행렬의 곱) O(C^m) 지수 (여행하는 외판원 문제, 집합 분할 문제) - 회사에서는 대개 정렬 루틴을 작성하느라 많은 시간을 쓰지 않는다. 대부분 여러분이 작성하는 것보다 성능이 더 나을 것이다. 하지만 앞에서 설명한 기본적인 알고리즘들은 계속해서 나타난다. (p.296)
리팩터링
- 밖으로 드러나는 동작은 그대로 유지한 채 내부 구조를 변경함으로써 이미 존재하는 코드를 재구성하는 체계적 기법 (p.301)
- 이 활동은 체계적이다. 아무렇게나 하는 것이 아니다
- 밖으로 드러나는 동작은 바뀌지 않는다. 기능을 추가하는 작업이 아니다
- 리팩터링은 여러분이 무언가를 알게 되었을 때 한다.
- 어쩌면 코드가 더는 잘 맞지 않아서 장애물에 부딪혔을 때, 두 가지가 사실은 하나로 합쳐져 있어야 한다는 것을 발견했을 때, 무엇이든 ‘잘못’되었다는 생각이 들 때가 있을 것이다. 주저하지 말고 변경하라.
- 마틴 파울러는 손해 보는 일이 없도록 리팩터링 하는 방법에 대하여 몇 가지 간단한 조언을 해 주었다.
- 리팩터링과 기능 추가를 동시에 하지 말라
- 리팩터링을 시작하기 전 든든한 테스트가 있는지 먼저 확인하라
- 단계를 작게 나누어서 신중하게 작업하라
테스트로 코딩하기
- 여러분은 왜 테스트를 해야 한다고 생각하는가? (p.307)
테스트는 버그를 찾기 위한 것이 아니다.
- 테스트는 우리의 코딩을 인도하는 필수 피드백이다. (p.309)
- 다른 코드와 긴밀하게 결합된 함수나 메서드는 테스트하기 힘들다. (p.309)
- TDD 발상의 핵심은 이 반복 주기가 기껏해야 몇 분 정도로 매우 짧아야 한다는 것이다. (p.311)
- “코끼리를 먹는 방법은 ?”이라는 해묵은 농담이 있다. 답은 “한 번에 한입씩”이고, 이는 TDD의 장점으로 흔히 언급되곤 한다. 전체 문제를 완전히 파악하기 힘들 때 한 번에 테스트 하나씩 작은 단계들을 밟는 것이다.
상향식이나 하향식이 아니라 끝에서 끝까지(end-to-end) 만들어라.
- 여러분에게 있는 선택지는 그리 많지 않다. “테스트 먼저”, “코드와 테스트를 함께”, “테스트하지 않음” 셋 중 하나다. (p.319)
- 최악의 선택은 흔히들 “나중에 테스트”라고 부르는 것인데, 완전 헛소리다. “나중에 테스트”는 사실 “테스트하지 않음”이란 뜻이다.
- 명심하라. 테스트는 프로그래밍의 일부다. 다른 사람이나 다른 부서에 떠넘길 수 있는 것이 아니다. (p.320)
도전해볼 것
- 여러분이 해야 한다는 것은 알지만 약간 무섭고 어려워 보여서 미뤄둔 일이 있는가? 이번 항목의 기법을 적용해 보라. (p.282)
궁금한 점
- 팀 내에서 다른 작업을 할 때, 실제로 알고리즘의 속도를 측정하기 위한 측정 방법 또는 기준을 가지고 있나요?
'Book Study' 카테고리의 다른 글
실용주의 프로그래머 8장 - 프로젝트 전에 (1) 2024.03.04 실용주의 프로그래머 9장 - 실용주의 프로젝트 (0) 2024.02.29 실용주의 프로그래머 스터디 2장 - 실용주의 접근법 (0) 2024.02.19 실용주의 프로그래머 스터디 1장 - 실용주의 철학 (1) 2024.02.14 실용주의 프로그래머 스터디 6장 - 동시성 (1) 2024.02.13