개발자 99% 커뮤니티에서 수다 떨어요!
오늘 TIL 3줄 요약
코딩은 기계적인 작업이 아니다.
테스트, 설계, 코딩 이 모든 것이 프로그래밍이다.
프로그래밍에서는 이름이 "모든 것"이다.
TIL (Today I Learned) 날짜
2022. 05. 27
오늘 읽은 범위
7장. 코딩하는 동안
책에서 기억하고 싶은 내용을 써보세요.
일단 코딩에 들어가면 대부분 기계적인 작업, 즉 설계 내용을 컴퓨터가 실행 할 수 있는 문장으로 바꾸는 일만 하면 된다고들 많이 생각한다. 우리가 보기에는 이런 태도가 소프트웨어 프로젝트가 실패하는 가장 큰 원인이다. 이런 태도 때문에 많은 시스템이 결국 너저분해지고, 비효율적이 되고, 구조가 망가지고, 유지 보수가 힘들어지고, 한마디로 완전히 잘못되고 만다.
실용주의 프로그래머는 모든 코드를 비판적인 시각으로 바라본다. 자기 자신의 코드도 예외가 아니다. 우리는 우리가 만든 프로그램과 설계에서 언제나 개선할 여지를 찾아낸다.
테스트는 버그를 찾는 작업이 아니다. 여러분의 코드에 대한 피드백을 받는 작업이다.
누구나 텅 빈 화면을 두려워한다. 아무것도 없는 가운데 외로이 깜빡이는 커서를 떠올려 보라. 새로운 프로젝트를 시작하는 일도 두렵기는 마찬가지다. 심지어 이미 있는 프로젝트에 새로운 모듈을 추가하는 일도 그렇다. 많은 사람이 일을 시작하는 첫 발짝을 미루고 싶어 한다.
본능이 하고자 하는 말을 경청하라. 우리의 본능은 우리가 행한 경험들을 기억함으로써 우리에게 경고하는 것일 지도 모른다. 그게 아니라면 우리는 그저 실수할까봐 두려운 것일 수도 있다. 그러나 우리가 전문가라고 생각해야 한다면 그래도 해내야 한다. 코드가 보내는 경고를 우리의 본능이 느끼고 우리에게 이야기 하는 것일 수도 있다. 그러니 우리는 우리의 본능에 주의를 기울여야 한다,
우리의 내면에 귀를 기울이는 방법은 간단하다. 일단 하던 일을 멈추고 정리를 할 수 있도록 시간과 공간을 확보하라. 가만히 내버려두면 정리가 되어 우리에게 다시금 깨닫게 해 줄 것이다. 그도 아니라면 다른 사람에게 설명해보라. 프로그래밍과 관련이 없는 사람이면 더 좋고 사람이 안된다면 특정 사물에게라도 이야기 해 보라. 그래도 되지 않는다면 프로토타이핑을 해 보라.
프로토타이핑 방법
포스트잇에 "프로토타이핑 중"이라고 써서 모니터 옆에 붙여라.
프로토타이핑은 원래 실패한다고 자신에게 상기시켜라. 실패하지 않더라도 프로토타입은 버리는 것이라는 점도 함께 상기시켜야 한다. 프로토타이핑으로 손해 볼 일은 없다.
텅 빈 에디터 화면에 여러분이 배우고 싶은 것 혹은 하고 싶은 것을 한 문장의 주석으로 표현해 보라.
코딩을 시작하라.
우연에 의지하지 말라. 인간은 언제나 패턴과 인과 관계를 찾으려고 한다. 그저 우연에 불과한 것들 속에서도 그렇다.
의도적으로 프로그래밍하라. 언제나 여러분이 지금 무엇을 하고 있는지 알아야 한다. 설명할 수 없다면 그것은 우연에 기대는 것이다. 계획을 세우고 그에 따르며, 신뢰할 수 있는 것에만 기대라. 가정을 기록으로 남겨라. 코드뿐만 아니라 가정 또한 테스트 해 보라.
과거의 노예가 되지 말라.
'대문자 O 표기법(Big-O notation)'이라고 부르는 근삿값을 기록하는 방식을 이용하라.
프로그램이 발전함에 따라 점점 초기에 내린 결정을 다시 고려하고 코드의 일부분을 다시 작성할 일이 생긴다. 이것은 지극히 자연스러운 과정이다. 코드는 정적인 존재가 아니다. 코드는 발전해야 한다.
소프트웨어 개발은 건축보다 정원 가꾸기에 더 가깝다. 딱딱하기보다는 유기적인 활동이다.
마틴 파울러 - 리팩터링 : 밖으로 드러나는 동작은 그대로 유지한 채 내부 구조를 변경함으로써 이미 존재하는 코드를 재구성하는 체계적 기법
여러분의 코드를 리팩터링하는 것 - 기능을 이리저리 옮기고 이전에 내린 결정을 바꾸는 것-은 사실 '고통 관리(pain management)'를 실천하는 것이다. 현실을 피하지 말자. 소스 코드를 이곳저곳 변경하는 것은 굉장히 고통스러운 작업일 수도 있다. 작동하는 코드이니 괜히 긁어 부스럼 만들지 않는 편이 나을 수도 있다. 가장 현실적인 문제는 일정의 압박일 것이다. 그러나 이는 설득력이 떨어지는 핑계다. 리팩터링이 필요한 코드는 종양에 비유할 수 있을 것이다. 종양은 방치하면 커진다. 커지기 전에 수습하라. 일찍 리팩터링하고, 자주 리팩터링 하라.
리팩터링의 본질은 재설계다. 리팩터링은 천천히, 신중하게, 조심스럽게 진행해야한다.
리팩터링과 기능 추가를 동시에 하지 말라.
리팩터링을 시작하기 전 든든한 테스트가 있는지 먼저 확인하라. 할 수 있는 한 자주 테스트를 돌려보라.
단계를 작게 나누어서 신중하게 작업하라. 클래스의 필드 하나를 다른 클래스로 옮기기, 메서드 하나 쪼개기, 변수명 하나 바꾸기 같이 작은 단위로 작업해야 한다. 리팩터링에서는 국지적인 변경들이 많이 모여서 커다란 규모의 변화를 낳는 일이 자주 발생한다. 단계를 작게 나누고, 한 단계가 끝날 때마다 테스트를 돌린다면 기나긴 디버깅 작업을 피할 수 있다.
테스트는 버그를 찾기 위한 것이 아니다. 테스트의 주요한 이득은 테스트를 실행할 때가 아니라 테스트에 대해 생각하고, 작성할때 생긴다.
테스트가 코드의 첫 번째 사용자다. 이것이 테스트가 주는 가장 큰 이득일지 모른다. 테스트는 우리의 코딩을 인도하는 필수 피드백이다.
다른 코드와 긴밀하게 결합된 함수나 메서드는 테스트하기 힘들다. 메서드를 실행하기도 전에 온갖 환경 구성을 한참 해야 하기 때문이다. 즉, 무언가를 테스트하기 좋게 만들면 결합도도 낮아진다. 또한 테스트를 하기 위해서는 우선 이해해야 한다.
테스트 주도 개발(test driven development, TDD)
추가하고 싶은 작은 기능 하나를 결정한다.
그 기능이 구현되었을 때 통과하게 될 테스트를 하나 작성한다.
테스트를 실행한다. 다른 테스트는 통과하고 방금 추가한 테스트 딱 하나만 실패해야 한다.
실패하는 테스트를 통과시킬 수 있는 최소한의 코드만 작성한다. 그리고 이제는 모든 테스트가 통과하는지 확인한다.
코드를 리팩터링한다. 방금 작성한 테스트나 함수를 개선할 수 있는 부분이 없는지 살펴본다. 개선한 후에도 테스트가 계속 통과하는지 확인한다.
TDD발상의 핵심은 이 반복 주기가 기껏해야 몇 분 정도로 매우 짧아야 한다는 것이다. 따라서 끊임없이 테스트 작성과 테스트를 통과하게 만들기를 반복하게 된다.
상향식이나 하향식이 아니라 끝에서 끝까지(end to end) 만들어라.
테스트, 설계, 코딩, 이 모든 것이 프로그래밍이다.
기본 보안 원칙
공격 표면을 최소화하라. : 시스템의 '공격 표면(attack surface)'영역은 공격자가 데이터를 입력하거나, 데이터를 추출하거나 서비스를 실행시킬 수 있는 모든 접근 지점을 합한 것이다.
코드의 복잡성은 공격 매개체를 유발한다.
입력 데이터는 공격 매개체다.
인증이 없는 서비스는 공격 매개체다.
인증을 요구하는 서비스도 공격 매개체다.
출력 데이터는 공격 매개체다.
디버깅 정보는 공격 매개체다.
최소 권한 원칙. : 최소한의 권한만을 꼭 필요한 시간만큼만 제일 짧게 부여하라
안전한 기본값. : 여러분의 애플리케이션 혹은 웹 사이트 사용자의 기본 설정은 가장 안전한 값이어야 한다.
민감 정보를 암호화하라.
보안 업데이트를 적용하라.
암호화에 있어서 첫 번째 규칙이자 가장 중요한 규칙은 절대 직접 만들지 말라는 것이다. 신뢰할 수 있는 것에만 의지하라. 많이 검토하고, 철저하게 검사하고, 잘 유시 보수되며 자주 업데이트되는 라이브러리와 프레임워크를 사용하라. 가급적 오픈 소스가 좋다.
프로그래밍에서는 이름이 "모든 것"이다.
이름에 깊은 의미가 있음을 보여 주는 과학 연구도 있다. 우리의 뇌가 단어를 읽고 이해하는 속도는 엄청나게 빨라서 다른 대부분의 활동보다 빠르다고 한다. 이 말은 무언가를 이해하려고 할 때 단어의 우선순위가 높다는 것이다. 스트루프 효과(Stroop effect)를 사용해서 실험해 볼 수 있다.
반드시 팀의 모든 사람이 각 단어의 뜻을 알고 일관성 있게 사용해야 한다.
이름을 잘 지어라. 필요하다면 이름을 바꿔라.
오늘 읽은 소감은? 떠오르는 생각을 가볍게 적어보세요
7장의 첫 문장이 가장 기억에 남았다. 설계 내용을 컴퓨터가 실행할 수 있는 문장으로 바꾸는 일만 하면 된다는 것. 어떤 일에도 변수가 있고, 세상 일이 설계한 대로만 흘러가지 않는다. 그렇기 때문에 유연한 구조가 필요하고 소통이 중요한 이유라고 볼 수 있다. 물론 설계 내용을 옮기지도 못하는 상황에서 그 다음 상황을 생각한다는 것은 기어가지도 못하는데 뛰는 것이라는 생각이 든다. 그럼에도 불구하고 이 책이 의미가 있는 것은, 기어가면서도 그 다음에 해야 할 것에 대한 생각을 하는 습관을 형성하는데 가이드라인이 되어준다는 느낌이다.
1인 개발자로써 혼자서 모든 것을 하는 것이 아닌 이상 소통은 필수적이다. 오로지 프로그래밍에서만 이야기하는 것이 아닌, 소프트웨어를 개발하는 모든 과정에 대해서 조언하고 있다는 점에서 이 책이 좋은 책이라는 것을 느낄 수가 있었다. 그렇다면 소통은 어떻게 해야하는가? 그에 대해서는 1장 7절에서 이미 충분히 설명되어 있으니 그걸 참고하면 되지 않을까. 책을 읽으면서 지속적으로 1장부터 다시 한번 참고하고 다시 읽으면서 해당 내용이 이렇게 연관지어져 있구나를 느끼게 되면서 점점 더 책 속 내용을 이해하는데 살이 붙는 느낌이다. 목차는 뼈대이고, 그 살을 채우는 것은 반복적인 내용 숙지와 정독, 그리고 이해다. 따라서 해당 챌린지에 참여한 내 자신이 조금 더 대견해지는 느낌이다.
물론 1인 개발자로써 혼자서 모든걸 한다 하더라도 어제의 나와 오늘의 나, 그리고 내일의 나는 다른 사람이라고 생각하는게 나을지도 모른다. 어제 내가 이해 했던 내용을 오늘의 나와 내일의 내가 이해할 수 있을 것이라는 생각이 들지는 않으니까.
코딩을 배우면서 꾸준히 들었던 생각은 프로그래머는 창작자다. 예술가다. 이 사람들은 창작의 고통을 매일 매 순간 느끼는 사람이다. 특히 변수, 함수, 클래스의 이름을 짓는 것은 너무나도 괴롭다. 심지어 해당 명칭은 명확하고 직관적으로 지어야 나중에 얘가 하는 역할이 무엇이었는지 헷갈리지 않는다. 작품을 만들기는 쉽지만 좋은 작품을 만드는 것은 어렵다. 마찬가지로 이름 짓기는 쉽지만 좋은 이름을 짓는 것은 어렵다. 말 그대로 이름은 "모든 것"이다. 좋은 것에 대한 사람들의 기호는 모두 다를지 몰라도 소프트웨어를 만드는 프로그래머의 입장에서는 이 책이 말하는 좋은 것이 가장 좋은 것이 아닐까라는 생각이 든다.
궁금한 내용이 있거나, 잘 이해되지 않는 내용이 있다면 적어보세요.
Big-O notation에 대해서는 이전에도 의문점을 가졌었고, 알고리즘 테스트를 준비하면서 한번 배우고 공부했던 개념이었다. 그런데 그때도 이해가 안됐지만 지금도 이해가 안되는 것은 내가 코딩 경험이 부족해서 그런게 아닌가 하는 생각이 든다. 그때는 보다 경험을 쌓고 다시 공부해보자 라고 생각했는데 지금도 마찬가지인 기분...꼭 메모해뒀다가 나중에 다시 공부해봐야겠다.
오늘 읽은 다른사람의 TIL