개발자 99% 커뮤니티에서 수다 떨어요!
오늘 TIL 3줄 요약
왜 코드가 망가졌는지 모르는 까닭은 애초에 코드가 왜 잘 돌아가는지도 몰랐기 때문이다.
가정하지 말라. 증명하라.
테스트, 설계, 코딩, 이 모든 것이 프로그래밍이다.
"내가 이것을 왜 만드는 거지?"
TIL (Today I Learned) 날짜
2022.04.01 - 2022.04.02
오늘 읽은 범위
6장. 코딩하는 동안
책에서 기억하고 싶은 내용을 써보세요.
코딩에 들어가면 대부분 기계적인 작업, 즉 설계 내용을 컴퓨터가 실행 할 수 있는 문장으로 바꾸는 일만 하면 된다고들 많이 생각한다
-> 이런 태도 떄문에 많은 시스템이 결국 너저분해지고, 비효율적이 되고, 구조가 망가지고, 유지 보수가 힘들어지고, 한마디로 완전히 잘못되고 만다.
코딩할 때는 매 순간 결정을 내려야 하는데, 프로그램이 정확하게 생산적으로 작동하면서 천수를 누리도록 하려면 사려 깊은 생각과 판단으로 결정을 내려야 한다.
그 생각과 판단에 도움을 주는 8가지 방법
머릿속에 맴돌곤 하는 소리를 더 주의 깊게 듣고 이에 적극적으로 반응하는 방법
-> 항목 37. 파충류의 뇌에 귀 기울이기
프로그래머가 코딩하는 동안 더 적극적으로 행동하는 방법
-> 항목 38. 우연에 맡기는 프로그래밍
코드 속도를 추정하는 방법을 논의. 성능 문제가 발생하기 전 미리 잠재적인 문제점을 찾아낼 때 유용한 비법 몇가지
-> 항목 39. 알고리즘의 속도
프로젝트를 진행하면서도 끊임없이 기존 코드를 개선할 수 있는 기법
-> 항목 40. 리펙터링
테스트의 긍정적인 효과는 대부분 테스트를 수행할 때 나타나는 것이 아니라, 테스트에 대하여 생각할 때 그리고 테스트를 작성할 때 나타난다는 것에 대한 탐구
-> 항목 41. 테스트로 코딩하기
어떻게 컴퓨터에게 넓은 범위의 테스트를 시킬 수 있을지, 그리고 당연하게도 버그가 나타났을 때 어떻게 대처할지
-> 항목 42. 속성 기반 테스트
바깥세상은 가혹하고, 여러분의 시스템에 뚦고 들어와서 해를 끼치려고 애를 쓰는 나쁜 사람들로 가득하다. 보안에 관련된 매우 기본적인 기법과 접근 방법
-> 항목 43. 바깥에서는 안전에 주의하라
우리가 고른 이름이 여러모로 우리가 만드는 현실을 정의한다. 코딩하는 동안 이름의 의미가 변하지는 않는지 늘 경계해야 한다.
-> 항목 44. 이름 짓기
본능이란 우리 뇌의 무의식 속에 채워져 있는 패턴에 대한 단순한 반응. 일부는 선천적이고, 나머지는 반복을 통해 습득
모든 본능에는 공통점이 있다.
말로 표현할 수 없다
생각이 아니라 느낌
감당하기 어려운 일처럼 느껴질 수도 있음
이러한 불안하고 초조한 본능을 느낄때 해결책은 일단 본능이 반응하고 있음을 인지하는 것
-> 왜 그런 느낌이 드는지 알아내야 한다!
프로그래머가 느끼는 두려운 상황들
: 텅 빈 화면, 아무것도 없는 가운데 외로이 깜박이는 커서, 새로운 프로젝트를 시작하는 일,
이미 있는 프로젝트에 새로운 모듈을 추가하는 일
-> 일을 시작하는 첫 발짝을 미루고 싶어 한다.
일을 시작하는 첫 발짝을 미루고 싶어하는 두 가지 원인
파충류의 뇌가 무언가 할 말이 있어서다.
인식의 지평 바로 밑에 도사리고 있는 모종의 의심이 있다. 이런 의심은 중요하다.
-> 직감이 여러분의 역량에 일조하도록 하라
그저 실수할까 봐 두려운 것일수 있음
코딩을 할 때 일보전진 이보후퇴식으로 코딩작업이 될 때
: 여러분의 코드가 무언가 말하려는 것이다. 지금 하는 작업이 필요 이상으로 힘들다고 말이다.
코드가 보내는 피드백을 파충류의 뇌가 느끼고 있는것이다.
일보전진 이보후퇴식 답답한 코딩작업 하는 상황일 때 해결책
일단, 하고 있는 일을 멈춰라.
여러분의 뇌가 정리를 좀 할 수 있도록 약간의 시간과 공간을 확보하라.
코드에 대해 생각하지 말고 키보드에서 떨어져서 잠깐 머리를 비운 채로 할 수 있는 일을 하라.
이 방법이 잘 안되면 문제를 표면으로 끄집어내 보라.
작성하는 코드에 대한 그림을 그려보라. 동료에게 설명해 보라.
여러분 뇌의 다른 부위에 문제를 노출하라.
위의 두 가지 방법들을 시도했음에도 여전히 막혀 있다면?
행동해야 할 시간이다.
여러분의 뇌에게 여러분이 하려는 일은 별 문제가 없다고 알려줘야 한다.
바로 프로토타이핑을 하면 된다.
프로토타이핑의 대상 예시
빈 스크린을 마주하고 있다면 프로젝트에서 시도해 보고 싶은 특정한 측면
새로운 프레임워크를 사용하고 있다면 데이터 바인딩(data binding)이 어떻게 일어나는 지 확인하기
새로운 알고리즘이 특수한 상황에서는 어떻게 되는지 확인하기
사용자 상호 작용을 몇 가지 다른 방식으로 시도해보기
프로토타이핑 하는 방법
포스트잇에 "프로토타이핑 중" 이라고 써서 모니터 옆에 붙여라
프로토타이핑은 원래 실패한다고 자신에게 상기시켜라.
실패하지 않더라도 프로토타입은 버리는 것이라는 점도 함께 상기시켜야 한다.
프로토타이핑으로 손해 볼 일은 없다.
텅 빈 에디터 화면에 여러분이 배우고 싶은 것 혹은 하고 싶은 것을 한 문장의 주석으로 표현해 보라(위의 프로토타이핑의 대상 예시 참고)
코딩을 시작하라
: 의심이 들기 시작하면 포스트잇을 보라!
프로토타이핑을 끝마쳤는대도 여전히 불안한 마음이 들면 다시 처음부터 시작하라.
첫 단계는 산책과 수다, 그리고 휴식이다.
다른 사람이 작성한 코드를 대할 때
다른 사람의 코드를 기계적으로 읽으면서 중요해 보이는 대목은 메모해 가며 묵묵히 시간을 투자하기
처리 방식이 이상해 보이는 부분이 눈에 띄면 적기, 패턴을 찾아보기, 다른 사람이 코드를 그런 식으로 작성해야만 했던 원인을 찾아낼 수 있다면 코드를 이해하는 일이 훨씬 더 쉬워질수 있다.
직감에 귀 기울이는 방법은 계속 갈고닦아야 할 중요한 기술이다.
본능에 귀를 기울이고 문제가 여러분 앞에 튀어나오기 전에 미리 대처하라
개발자인 우리들 역시 지뢰밭에서 일한다. 하루에도 수백 개가 넘는 함정이 우리가 빠지기를 기다리고 있다.
우리는 우연에 맡기는 프로그래밍, 곧 행운과 우연한 성공에 의존하는 프로그래밍을 하지 않아야 한다.
-> 대신 '의도적으로 프로그래밍' 해야 한다.
단순히 코드가 지금 작성된 방식이 그렇기 때문에 생기는 우연에 의해 잘 작동되고 있는 코드를 건드려야 만 하는 이유 몇 가지
정말로 제대로 돌아가는 게 아닐지도 모른다.
여러분이 의존하는 조건이 단지 우연인 경우도 있다.
문서화되지 않은 동작은 라이브러리의 다음 릴리스에서 변경될 수도 있다.
불필요한 추가 호출은 코드를 더 느리게 만든다.
추가로 호출한 루틴에 새로운 버그가 생길 수도 있다.
다른 루틴을 호출할 때도 문서화된 동작에만 의존하라. 어떤 이유로든 그럴 수 없다면 추측을 문서로 상세히 남겨라.
확고한 사실에 근거하지 않은 가정은 어떤 프로젝트에서든 재앙의 근원이 된다.
의도적으로 프로그래밍 하기
언제나 여러분이 지금 무엇을 하고 있는지 알아야 한다.
더 경험이 적은 프로그래머에게 코드를 상세히 설명할 수 있는가?
자신도 잘 모르는 코드를 만들지 말라
계획을 세우고 그것을 바탕으로 진행하라
신뢰할 수 있는 것에만 기대라. 가정에 의존하지 말라.
가정을 기록으로 남겨라
코드뿐 아니라 여러분이 세운 가정도 테스트해 보아야 한다.
노력을 기울일 대상의 우선순위를 정하라
과거의 노예가 되지 말라. 기존 코드가 앞으로 짤 코드를 지배하도록 놓아두지 말라.
필요한 변경을 하지 않을 경우의 비용보다 일정이 늦어져서 발생하는 비용이 적어야 한다는 것을 염두에 두어라.
실용중의 프로그래머가 거의 날마다 하는 또다른 종류의 추정이 있다.
바로 알고리즘이 사용하는 자원, 곧 시간, 프로세서, 메모리 등을 추정하는 것이다.
상식을 이용해서 간단한 알고리즘들의 차수를 추정할 수 있다.
단순 반복문 : O(n)
수행 시간은 n에 비례해서 증가
소진 탐색(exhaustive search), 배열에서 최댓값 찾기, 체크섬 생성하기
중첩 반복문 : O(m x n)
m과 n은 두 반복문의 반복 횟수. n의 제곱이 되기 쉬움
버블 정렬처럼 간단한 정렬 알고리즘에서 나타남
반씩 자르기: O(lg n)
반복문을 돌 때마다 작업 대상의 수를 반으로 줄여 나가는 알고리즘
정렬된 목록의 이진검색, 이진 트리의 탐색, 정수의 2진수 표현에서 첫 번째 1인 비트를 찾기
분할 정복(divide and conquer): O(n lg n)
입력 데이터를 둘로 나눠서 각각 독립적으로 작업한 다음, 결과를 합치는 알고리즘
퀵 정렬(quicksort)
조합적(combinatoric): O(C의 n제곱)
알고리즘이 항목의 순열을 다루기 시작하면 대부분의 경우 수행시간은 걷잡을 수 없이 늘어난다.
'난해(hard)'하다고 분류되는 문제를 푸는 알고리즘이 대부분 여기에 속함
O(n의 2제곱) 알고리즘이 있다면 분할 정복을 사용하여 O(n lg n) 으로 줄일 수 없는지 시도해보라
코드의 실행 시간이 얼마나 될지 또는 메모리를 얼마나 사용할 지 확실하지 않다면 직접 실행해보라
: 입력 레코드의 수나 혹은 실행 시간에 영향을 줄 것 같은 요소라면 모두 바꾸어 가면서 실행해 본 다음, 결과를 그래프로 그려보자.
가장 빠른 알고리즘이 언제나 가장 좋은 알고리즘은 아니다.
'성급한 최적화'(premature optimization)를 조심하라
: 언제나 어떤 알고리즘을 개선하느라 여러분의 귀중한 시간을 투자하기 전에 그 알고리즘이 정말로 병목인지 먼저 확인하는 것이 좋다.
소프트웨어 개발은 건축보다 정원 가꾸기에 더 가깝다. 딱딱하기보다는 유기적인 활동이다.
마틴 파울러가 정의한 '리펙터링'
: 밖으로 드러나는 동작은 그대로 유지한 채 내부 구조를 변경함으로써 이미 존재하는 코드를 재구성하는 체계적 기법
위의 정의에서 핵심 두 가지
이 활동은 체계적이다. 아무렇게나 하는 것이 아니다.
밖으로 드러나는 동작은 바뀌지 않는다. 기능을 추가하는 작업이 아니다.
리펙터링을 식물을 다시 심기 위해 정원 전체를 갈아엎듯이 해서는 안 된다.
리펙터링은 그런 게 아니라 잡초 제거나 갈퀴질처럼 위험하지 않은 작은 단계들을 밟는 일상 활동이다.
밖으로 드러나는 동작이 바뀌지 않는다는 것을 보장하려면 코드의 동작을 검증하는 좋은 자동화된 단위 테스트가 필요하다.
리펙토링은 언제하는가?
: 무언가를 알게 되었을 때 한다.
어쩌면 코드가 더는 잘 맞기 않아서 장애물에 부딪혔을 때,
두 가지가 사실은 하나로 합쳐져 있어야 한다는 것을 발견했을 때,
무엇이든 '잘못' 되었다는 생각이 들 때
-> 주저하지 말고 변경하라!
코드를 리펙터링 하는 것 - 기능을 이리저리 옮기고 이전에 내린 결정을 바꾸는 것 - 은 사실 '고통 관리(pain management)'를 실천하는 것이다.
일정의 압박은 리펙터링을 하지 않는 단골 핑계다.
: 리펙터링이 필요한 코드를 일종의 '종양'이라고 생각하자!
대부분의 일처럼 리펙터링도 문제가 작을 때, 코딩하는 동안 함께 진행하는 편이 더 쉽다.
일정에 리펙터링 할 시간을 확실히 포함시켜 두도록 하자!
리펙터링의 본질은 재설계다.
분명히 리펙터링은 천천히, 신중하게, 조심스럽게 진행해야 하는 작업이다.
마틴 파울러의 리펙터링하는 방법에 대한 몇 가지 조언
리펙터링과 기능 추가를 동시에 하지 말라
리펙터링을 시작하기 전 든든한 테스트가 있는지 먼저 확인하라
단계를 작게 나누어서 신중하게 작업하라
마틴 파울러가 한 조언의 핵심은 탄탄한 회귀 테스트를 유지하는 것이야말로 안전한 리펙터링의 비결이라는 것이다.
리펙터링만으로는 부족해서 결국 외부에서 보이는 동작이나 API를 바꿔야 한다면, 일부러 빌드를 깨트려 보는 것이 유용할 수도 있다.
리펙터링 대상 코드에 의존하는 옛날 코드들은 컴파일이 안 되게 만드는 것이다.
이렇게 하면 고쳐야 하는 부분이 어디인지 알아낼 수 있다.
지금은 고통스러울지라도 앞으로 더욱 고통스러워질 것 같으면 지금 고치는 편이 낫다.
우리가 생각하는 테스트의 중요한 가치는 무엇일까? 왜 테스트를 해야 한다고 생각하는가?
-> 테스트는 버그를 찾기 위한 것이 아니다!
우리는 테스트의 주요한 이득이 테스트를 실행할 때가 아니라 테스트에 대해 생각하고, 테스트를 작성할 때 생긴다고 믿는다.
우리 메서드의 테스트 작성에 대해 생각함으로써 코드의 작성자가 아니라 사용자인 것처럼 메서드를 외부의 시선으로 보게 되었다.
-> 테스트가 코드의 첫 번째 사용자다.
이것이 테스트가 주는 가장 큰 이득일지 모른다. 테스트는 우리의 코딩을 인도하는 필수 피드백이다.
무언가를 테스트하기 좋게 만들면 결합도도 낮아진다.
무언가를 테스트하려면 그것을 이해해야만 한다.
코딩을 시작하기 전에 경계 조건의 테스트와 경계 조건에서 어떻게 동작해야 하는지를 먼저 생각해본다면, 아마 함수를 단순하게 만드는 코드 패턴을 찾을 수 있을 것이다.
테스트 주도 개발(test drive development, TDD)
: 테스트를 먼저 작성하자고 주장하는 프로그래밍 기법
TDD의 기본주기
추가하고 싶은 작은 기능 하나를 결정한다.
그 기능이 구현되었을 때 통과하게 될 테스트를 하나 작성한다.
테스트를 실행한다. 다른 테스트는 통과하고 방금 추가한 테스트 딱 하나만 실패해야 한다.
실패하는 테스트를 통과시킬 수 있는 최소한의 코드만 작성한다. 그리고 이제는 모든 테스트가 통과하는지 확인한다.
코드를 리펙터링한다. 방금 작성한 테스트나 함수를 개선할 수 있는 부분이 없는지 살펴본다. 개선한 후에도 테스트가 계속 통과하는지 확인한다.
TDD 발상의 핵심의 위의 반복 주기가 기껏해야 몇 분 정도로 매우 짧아야 한다는 것이다.
하지만 TDD 의 노예가 되지는 말아야 한다. 그 징후로는
늘 테스트 커버리지 100%를 달성하기 위해 과도하게 많은 시간을 투자
많은 수의 중복 테스트가 생김
밑에서부터 시작하여 위로 올라가는 방식으로 설계를 함
어떻게든 TDD를 실천하라. 하지만 도중에 이따금 멈추어 큰 그림을 살피는 것을 잊지 말라
상향식이나 하향식이 아니라 끝에서 끝까지(end to end) 만들어라!
: 하향식 - 해결하려는 문제 전체를 가지고 시작. 문제를 몇 개의 조각으로 쪼개고 또 각각을 더 작은 조각으로 쪼개기를 반복해서 조각을 코드로 표현할 수 있을 만큼 작게 만듬
상향식 - 집을 짓듯이 코드를 쌓아 올림. 바닥에서부터 시작.
풀려는 문제에 가까운 추상적 개념을 만드는 코드 계층을 한 층 한 층 쌓아올림.
: 하향식, 상향식 모두 잘 안 된다. 가장 중요하게도 개발을 처음 시작할 때는 우리가 무엇을 하고 있는지 확실하게 모른다.
한쪽 끝과 다른 쪽 끝을 잇는 조그만 기능 조각들을 만들고, 그 과정에서 문제에 대하여 배워라.
명백히 테스트는 개발을 이끌어 나가는 데 도움이 된다. 하지만 나아갈 때마다 목적지를 떠올리지 않으면 계속 같은 자리만 빙빙 돌게 될 수도 있다.
소프트웨어 단위 테스트란 어떤 모듈에게 이것저것을 시켜보는 코드를 가리킨다.
우리는 단위 테스트를 계약을 잘 지키는지 보는 테스트라고 여긴다.
어떤 코드 단위가 자신이 맺은 계약을 지키는지 확인하는 테스트 케이스에서 알 수 있는 두 가지
코드가 계약을 지키는지 여부
코드로 표현된 계약의 의미가 우리가 생각한 것과 일치하는지 여부
'임시(Ad-hoc) 테스트'는 우리가 직접 코드를 이리저리 찔러보는 것이다. console.log() 한 줄일 수도 있고, 디버거나 IDE 환경, REPL(Read Eval Print Loop)에 직접 실행하면서 입력하는 코드 조각일 수도 있다.
어떤 모듈의 내부 상태를 디버거 없이 다양한 형태로 볼 수 있는 방법을 제공할 수도 있다.
로그 파일에 쌓이는 추적(trace) 메시지
'단축키' 조합이나 숨겨진 URL 방식
;기능 스위치(feafure switch)'를 활용하여 특정 사용자나 사용자 집단에 대해서는 진단 메시지를 더 많이 남기기
테스트 코드를 다른 제품 코드와 마찬가지로 다뤄라. 결합도를 낮추고, 깨끗하고 견고하게 유지하라.
코드가 지켜야 하는 '계약'을 코드에 포함
: 선행 조건에 맞추어 입력을 넣으면 코드가 생산하는 출력이 주어진 후행 조건에 맞음을 보장
'불변식(invariant)'
: 함수 실행 전후로 계속 어떤 부분의 상태에 대하여 참이 되는 조건
코드에 존재하는 계약과 불변식을 뭉뚱그려서 '속성(property)'이라고 부른다.
: 코드에서 속성을 찾아내서 테스트 자동화에 사용할 수 있는데, 이것으 '속성 기반 테스트(property based testing)'라 한다.
-> 속성 기반 테스트로 가정을 검증하라!
속성 기반 테스트가 강력한 까닭은 그저 입력을 생성하는 규칙과 출력을 검증하는 단정문만 설정한 채 제멋대로 작동하도록 놔두기 때문이다.
속성 기반 테스트가 실패했다면 테스트 함수가 어떤 매개 변수를 사용했는지 알아낸 다음 그 값을 이용하여 별도의 단위 테스트를 정식으로 추가하는 것이 좋다. 이 단위 테스트의 두 가지 역할.
속성 기반 테스트의 여러 가지 다른 수행 결과와 상관없이 문제가 발생하는 상황에 집중할 수 있다.
단위 테스트가 '회귀 테스트(regression test)'역할을 한다.
속성 기반 테스트는 여러분이 코드를 불변식과 계약이라는 관점으로 바라보게 한다.
여러분은 무엇이 변하지 않아야 하고, 어떤 조건을 만족해야 하는지 생각하게 된다.
고된 오르막길을 오르는 동안 고비와 난관을 여럿 거치고나면 자신에게 이렇게 말하기 일쑤다.
"휴, 이제 된다!" 그러고는 코드가 완성되었음을 선포한다. 물론 아직 완성되지 않았다.
여러분은 90% 완성한 것이다. 하지만 이제는 나머지 90%를 고려해야 한다.
내부에서 발생하는 오류뿐 아니라 외부에서 시스템을 망가트리려 하는 시도까지 고려해야 한다.
기본 보안 원칙
공격 표면을 최소화 하라
: 복잡한 코드는 예상 외의 부작용이 일어날 확률을 높이고, 결과적으로 공격 표면을 넓인다.
외부의 데이터를 절대 신뢰하지 말라.
본질적으로 인증이 없는 서비스는 전 세계 누구든지 호출할 수 있다.
인증 받은 사용자의 수를 언제나 최소로 유지하라. 쓰이지 않거나, 오래되고, 유효하지 않은 사용자나 서비스를 정리하라.
출력 데이터는 공격 메개체다.
디버깅 정보는 공격 매개체다.
최소 권한 원칙
: 최소한의 권한만을 꼭 필요한 시간만큼만 제일 짧게 부여하라
아무 생각 없이 root나 Administrator 같은 최고 수준 권한을 사용하지 말라.
안전한 기본값
: 여러분의 애플리케이션 혹은 웹 사이트 사용자의 기본 설정은 가장 안전한 값이어야 한다.
민감 정보를 암호화하라
: 개인 식별 정보나 금융 데이터, 비밀번호, 다른 인증 정보를 일반 텍스트로 남기지 말라. 데이터 베이스든 다른 파일이든 동일하다.
보안 업데이트를 적용하라
암호화는 직접 하지 않는 편이 낫다
: 신뢰할 수 있는 것이만 의지하라. 많이 검토하고, 철저하게 검사하고, 잘 유지 보수되며 자주 업데이트되는 라이브러리와 프레임워크를 사용하라. 가급적 오픈 소스가 좋다.
프로그래밍세너는 이름이 "모든 것!" 이다.
-> 이름은 여러분의 의도와 믿음을 잔뜩 드러내기 때문이다.
우리는 코드에서 하는 역할에 따라 이름을 지어야 한다고 믿는다. 이 말은 무언가를 만들 때마다 잠시 멈춰서 '내가 이것을 왜 만드는 거지?' 하고 생각해야 한다는 뜻이다.
'내가 이것을 왜 만드는 거지?'
-> 여러분이 문제 풀이 사고방식에서 벗어나 더 큰 그림을 보도록 하기 때문이다.
이름을 지을 때는 여러분이 표현하고 싶은 것을 더 명확하게 다듬기 위해 끊임없이 노력해야 한다.
이렇게 명확하게 다듬는 작업이 여러분이 코드를 작성할 때 코드를 더 잘 이애햘 수 있도록 도울 것이다.
이름 짓기 시 생각해야 할 사항
문화를 존중하라
: 프로그래밍 하는 기반의 문화가 녹아있는 단어를 사용
일관성
: 모든 프로젝트에는 팀 내에서 특별한 의미가 있는 용어들을 비롯하여 고유의 어휘들이 있다.
의도를 제대로 표현하지 못하거나 오해를 부를 수 있거나 햇갈리는 이름을 발견했다면 고쳐야 한다.
-> 이름을 잘 지어라. 필요하면 이름을 바꿔라
오늘 읽은 소감은? 떠오르는 생각을 가볍게 적어보세요
이 책의 모든 내용들이 뼈에 새겨야 할 내용들이지만 이번 7장의 내용은 실용주의 프로그래머로 거듭나기 위해선 실제 프로그래밍을 하는 동안 반드시 지켜야 할 바이블 같은 내용이였다.
7장의 내용이 많았지만 어느 내용 하나라도 놓쳐서는 안될 내용들이라고 내 '본능'이 감지해 버렸기 때문에 7장의 내용이 어려운 내용이 많아서라기 보다는 언제나 상기시켜야 겠다! 라고 생각하고 읽어서인지 여태까지의 장들중에 가장 오랜시간을 들여서 읽었다.
궁금한 내용이 있거나, 잘 이해되지 않는 내용이 있다면 적어보세요.
스래싱(thrashing) : 과도한 메모리 사용으로 인하여 지속해서 페이지 폴트가 발생하는 상황을 말한다. 그 결과 시스템의 성능이 급격하게 떨어진다.
오늘 읽은 다른사람의 TIL