diff --git "a/6\354\236\245/\353\260\261\354\247\200\354\227\260.md" "b/6\354\236\245/\353\260\261\354\247\200\354\227\260.md" index 4c3f6dd..b4969c1 100644 --- "a/6\354\236\245/\353\260\261\354\247\200\354\227\260.md" +++ "b/6\354\236\245/\353\260\261\354\247\200\354\227\260.md" @@ -1,4 +1,4 @@ -# 6장. 동시성 +# 6장 동시성 ### 동시성 diff --git "a/7\354\236\245/\353\260\261\354\247\200\354\227\260.md" "b/7\354\236\245/\353\260\261\354\247\200\354\227\260.md" new file mode 100644 index 0000000..ce2fbfa --- /dev/null +++ "b/7\354\236\245/\353\260\261\354\247\200\354\227\260.md" @@ -0,0 +1,164 @@ +# 7장 코딩하는 동안 + +## Topic 37 파충류의 뇌에 귀 기울이기 + +프로그래머로서 경험이 늘어갈수록 암묵적인 지식이 쌓인다. +잘 되는 방법, 잘 안되는 방법, 오류 형태별로 가능한 원인 등 일하는 동안 보고 듣고 느끼는 모든 것이 쌓인다. +의심이 계속 남아있거나 왠지 꺼림칙하다면, 그 느낌을 따라라. 직감이 여러분의 역량에 일조하도록 하라. +본능, 무의식, 파충류의 뇌에게 귀 기울이기를 바란다. + +파충류와 이야기하는 법 + +- 일단 하고 있는 일을 멈춰라. 언젠가는 다시 생각이 의식의 영역으로 올라와서 '아하!'하는 순간이 올 것이다. +- 이 방법이 잘 안되면 문제를 표면으로 끄집어내 보라. (코드를 그림으로 표현하거나 러버덕 디버깅) +- 프로토타이핑 + +## Topic 38 우연에 맡기는 프로그래밍 + +행운과 우연한 성공에 의존하는 대신 '의도적으로 프로그래밍'해야 한다. +왜 코드가 망가졌는지 모르는 까닭은 애초에 코드가 왜 잘 돌아가는지도 몰랐기 때문이다. +잘 돌아가는 듯이 보이는데 그 이유를 모를 경우, 우연은 아닌지 반드시 확인하라. + +## Topic 39 알고리즘의 속도 + +실용주의 프로그래머가 하는 2가지 종류의 추정 + +1. 프로젝트를 끝마치는 데 걸리는 기간 +2. 알고리즘이 사용하는 자원(시간, 프로세서, 메모리 등) + +### 알고리즘을 추정한다는 말의 의미 + +일반적으로 입력의 크기는 알고리즘에 영향을 준다. +입력의 크기가 클수록 알고리즘의 수행 시간이 길어지거나 사용하는 메모리 양이 늘어난다. +반복문이나 재귀 호출을 작성할 때면 수행 시간과 필요한 메모리 양을 계산하게 된다. +생각보다 상세한 분석이 필요한 경우도 있는데, 이럴 때 **대문자 O 표기법**이 유용하다. + +### 대문자 O 표기법 + +상한을 기술하는 표기법 +O(n²) : 함수가 실행되는 데 걸리는 시간의 최댓값이 n²보다 더 빨리 늘어나지 않는다는 뜻 + +n이 커질수록 가장 큰 차수가 아닌 다른 차수는 무시해도 될 정도이기 때문에 +관습적으로 최상위 차수를 제외한 다른 모든 차수는 제거하며, 상수인 계수도 표기하지 않는다. +입력의 크기가 바뀜에 따라 수행 시간이나 메모리가 어떻게 바뀔지를 알려주는 것이다. (실제 숫자는 아님) + + + +### 상식으로 추정하기 + +상식을 이용해 간단한 알고리즘의 차수 추정 가능 + +- 단순 반복문 : O(n) +- 중첩 반복문 : O(n²) +- 반씩 자르기 : O(lgn) +- 분할 정복 : O(nlgn) +- 조합적 : 순열을 다루기 시작하면 대부분의 경우 수행 시간은 걷잡을 수 없이 늘어남 + +### 실전에서의 알고리즘 속도 + +O(n²) 알고리즘이 있다면 분할 정복을 통해 O(nlgn)으로 줄일 수 없는지 시도해 보라. + +어떤 일을 하는 코드인지 코드 자체에 대해서도 생각해 보라. +입력값 n이 작을 경우, 단순한 O(n²) 코드가 복잡한 O(nlgn) 코드보다 더 좋은 성능을 내기도 한다. + +가장 빠른 알고리즘이 언제나 가장 좋은 알고리즘은 아니기 때문에 적당한 알고리즘을 선택할 줄 알아야 한다. +선택한 알고리즘이 요구하는 형식에 맞게 입력 데이터를 준비하는 데 비용이 많이 드는 것은 아닌지 확인해야 한다. +알고리즘 개선에 시간을 투자하기 전에 그 알고리즘이 정말로 병목인지 먼저 확인해야 한다. + +## Topic 40 리팩터링 + +마틴 파울러가 정의한 리팩터링 : **밖으로 드러나는 동작은 유지**한 채 내부 구조를 변경함으로써 이미 존재하는 코드를 재구성하는 **체계적** 기법 + +코드를 리팩터링 할 이유에는 '중복, 직교적이지 않은 설계, 더 이상 유효하지 않은 지식, 사용 사례, 성능, 테스트 통과'가 있다. +안전한 리팩터링의 비결은 탄탄한 회귀 테스트를 유지하는 것이다. + +> 7장 전까지 읽었던 내용을 요약해 주는 것 같은 토픽이었습니다👍 + +## Topic 41 테스트로 코딩하기 + +테스트가 코드의 첫 번째 사용자다. +다른 코드와 긴밀하게 결합된 함수나 메서드는 테스트하기 힘들다. +무언가를 테스트하기 좋게 만들면 결합도도 낮아진다. + +TDD의 기본 주기 + +1. 추가할 기능 결정 +2. 기능이 통과하게 될 테스트 하나 작성 +3. 테스트를 실행해 방금 추가한 테스트만 실패하는지 확인 +4. 실패하는 테스트를 통과시킬 최소한의 코드 작성 +5. 리팩터링을 하고, 이후에도 계속 테스트 통과하는지 확인 + +## Topic 42 속성 기반 테스트 + +내가 함수를 구현하고 테스트까지 작성하면, 나의 잘못된 가정이 함수와 테스트에 들어가 테스트를 통과할 수도 있다. +하지만 컴퓨터에게 테스트를 맡기면 이런 문제도 해결할 수 있다. + +지켜야 하는 **계약**을 코드에 포함해야 한다. +선행 조건에 맞게 입력이 들어오면 출력이 후행 조건에 맞음을 보장해 준다. +함수 실행 전후로 어떤 부분의 상태에 대하여 계속 참이 되는 조건이 **불변식**이다. +예를 들어, 정렬된 리스트는 정렬 전 리스트와 원소 수가 같으므로 리스트 길이가 불변식이다. +이렇게 코드에 존재하는 계약과 불변식을 뭉뚱그려서 **속성**이라고 한다. +코드에서 속성을 찾아내서 테스트 자동화에 사용할 수 있는데, 이를 **속성 기반 테스트**라고 한다. + +속성 기반 테스트로 잘못된 가정을 찾을 수 있다. + +## Topic 43 바깥에서는 안전에 주의하라 + +내부에서 발생하는 오류뿐 아니라 외부에서 시스템을 공격하는 시도까지 고려해야 한다. + +### 기본 보안 원칙 + +#### 1. 공격 표면을 최소화하라. + +공격 표면 영역 : 공격자가 데이터를 입력/추출하거나 서비스를 실행시킬 수 있는 모든 접근 지점을 합한 것 +복잡한 코드는 부작용이 일어날 확률을 높이고, 결과적으로 공격 표면을 넓히기 때문에 단순하고 작은 코드가 더 낫다. +외부 데이터에서 나쁜 내용을 제거한 뒤 다른 처리 루틴에 전달하라. +인증이 없는 서비스는 누구든지 호출할 수 있기에 별도 처리나 제한이 필요하다. +인증받은 사용자의 수를 언제나 최소로 유지하라. +응답 데이터가 사용자의 권한에 적절한지 늘 확인하라. +화면에 디버깅을 돕기 위한 정보가 노출되면 해커가 악용할 수 있다. + +#### 2. 최소 권한 원칙 + +최소한의 권한을 꼭 필요한 시간만큼만 짧게 부여해라. + +#### 3. 안전한 기본값 + +기본 설정은 가장 안전한 값이어야 한다. +ex. 비밀번호 입력 시 \*로 표시되는 게 기본값이라면, 주변에 많은 사람이 있는 환경에서 비밀번호를 숨길 수 있어 좋다. +> 이런 간단한 처리도 안전한 기본값에 해당된다는 게 신선했습니다. + +#### 4. 민감정보를 암호화하라. + +개인 식별 정보나 금융 데이터, 비밀번호, 다른 인증 정보를 일반 텍스트로 남기지 말라. +데이터가 유출되더라도 암호화가 안전장치 역할을 할 수 있어야 한다. + +#### 5. 보안 업데이트를 적용하라. + +데이터 유출 사고 중 가장 큰 사고는 업데이트를 하지 않은 시스템 때문에 발생했다. +> 보안 업데이트 보니까 저는 dependabot이 떠오르네요. +> 여러분은 dependabot을 잘 활용하고 계신가요? +> 제가 담당했던 레거시 프로젝트는 무려 3년 전에 axios를 설치한 채로 방치되었고, dependabot PR 마저도 close된 상황이었어요. +> major version upgrade가 필요해서 부담되긴 했지만, 아래와 같이 태스크를 생성해 개선했던 경험이 있습니다. +> +> + +## Topic 44 이름 짓기 + +의도와 역할이 드러나게 이름을 짓는 것이 중요하다. +> 직관적인 이름 짓기에는 역시 한글 코딩이 최고죠 +> https://tosspayments-dev.oopy.io/chapters/frontend/posts/hangul-coding-convention +> 이런 컨벤션만 팀에서 잘 정한다면 한글을 사용해도 괜찮다고 생각합니다. + +모든 프로젝트에는 팀 내에서 특별한 의미가 있는 용어가 있다. +ex. `Order` : 온라인 상점을 만드는 팀에게는 '주문', 종교 단체의 역사를 보여주는 앱을 만드는 팀에게는 '교단'을 의미 + +반드시 팀의 모든 사람이 각 단어의 뜻을 알고 일관성 있게 사용해야 한다. +특별한 의미가 있는 단어를 모두 모은 **프로젝트 용어 사전**을 만드는 방법도 있다. +> 회사 노션에 용어 사전 테이블 하나 만들어서 '국문, 영문, 설명, 결정 근거'를 작성하고 있어요. +> API, 코드 레벨에서 용어를 통일할 수 있다는 점이 좋은 것 같아요. + +의도를 제대로 표현하지 못하거나 오해를 부를 수 있거나 헷갈리는 이름을 발견했다면 고쳐야 한다. +> 이것도 제가 담당했던 업무 중 하나네요😅 +> 처음에는 prediction model이라는 용어를 사용했는데, +> 기능이 확장되면서 더 큰 개념을 가지는 machine learning으로 수정한 경험이 있습니다.