블로그
전체 10#카테고리
- 백엔드
#태그
- CS
- cs
- 발자국
- 미션
- 워밍업클럽
- 테스트코드
- 클린코드
2025. 06. 15.
0
인프런 워밍업 클럽 스터디 4기 - CS 전공지식 > 컴퓨터 구조 3주차 미션
◼컴퓨터 구조 1. STOREB(1001) 명령어를 만들어보세요.(OPcode는 1001이고 operand가 가리키는 RAM주소에 현재 레지스터B의 데이터 저장하는 기능)step0) Fetch0 CO, MI핀 활성화PC의 명령어 주소를 MAR에 전달 step1) Fetch1 RO, II, CE 핀 활성화MAR에 지정된 메모리에서 명령어를 읽어와 IR에 저장 후 PC 값 1 증가 step2) StoreB0 IO, MI핀 활성화명령어의 하위 비트(피연산자의 주소)를 MAR에 저장step3) StoreB1 BO, RI핀 활성화레지스터 B의 값을 RAM의 MAR 주소 위치에 저장 2. A와 B를 비교해서 A와 B가 같으면 0, A가 더 크면 1, B가 더 크면 2를 출력 레지스터에 출력하는 어셈블리어를 작성해보세요.
CS
2025. 06. 12.
0
인프런 워밍업 클럽 스터디 4기 - CS 전공지식 > 3주차 발자국
◼만들면서 쉽게 배우는 컴퓨터 구조Section8) 제어 장치가 없는 컴퓨터 제어 장치가 없는 컴퓨터명령어 실행시 MI, RI, RO, II, IO, AI, AO, BI, BO, EO, SU 등의 제어 신호를 외부에서 직접 활성화해주는 방식예시RAM의 15번지 값 5를 레지스터 A에 저장 Section9) CPU 만들기: 제어 장치 (Control Unit) 1바이트 기계 명령어상위 4비트(Opcode) + 하위 4비트(주소 또는 값)로 구성종류 (Opcode)NOP (0000), LOADA(0001), ADD(0010), SUB(0011), STOREA(0100), LOADI(0101), JMP(0110), JMPC(0111), JMPZ(1000), OUT(1110), HLT(1111) Program Counter (PC)다음에 실행할 명령어의 주소를 저장하는 레지스터보통 클럭 신호에 맞춰 1씩 증가하며 명령어를 순차적으로 실행하지만, 조건에 따라 특정 주소로 점프(Jump) 하기도 한다. 스텝 카운터(Step Counter)시스템 내에서 현재 동작이 몇 번째 단계(스텝)인지 추적하는 카운터어떤 동작이 여러 단계(Step 0, Step 1, Step 2, ...)로 나뉘어 있을 때, 지금 어느 단계인지 기억하고 다음 단계로 이동하기 위해 사용되는 카운터 제어장치 (Control Unit)NOP, LOADA, ADD, SUB, STOREA, LOADI, JMP, JMPC, JMPZ, OUT, HLT, 출력 레지스터로 구성 Section10) 기계어와 어셈블리 어셈블리어어셈블리어는 기계어(Machine Code)를 사람이 조금 더 이해하기 쉬운 형태로 바꾼 언어예시 어셈블러어셈블리어로 작성된 코드를 컴퓨터가 실행할 수 있는 기계어(이진 코드)로 변환해주는 프로그램 ◼ 그림으로 쉽게 배우는 자료구조와 알고리즘Section7) 트라이와 자동완성 트라이(Trie)문자열을 저장하고 검색하는 데 특화된 트리 자료구조루트부터 리프까지의 경로가 하나의 단어효율적인 자동완성, 사전 검색, 접두사 검색에 사용됨사용 예: 검색창 자동완성, 입력기 등 Section8) 그래프 그래프정점(Vertex)과 간선(Edge)으로 이루어진 자료구조방향 그래프: 간선에 방향이 있음 (ex: A → B)무방향 그래프: 간선에 방향 없음 (ex: A—B)탐색 방법DFS : 한 방향으로 계속 깊이 들어가며 탐색하는 방식 BFS : 가까운 정점부터 차례대로 탐색하는 방식표현 방식인접 행렬: 2차원 배열로 표현인접 리스트: 각 정점이 연결된 정점을 리스트로 표현 Section9) 가중 그래프각 간선(Edge)에 숫자 값(가중치, 비용, 거리 등)이 부여된 그래프예) 도시간 거리 그래프 🗒회고지난 주차에 배웠던 RAM, Register, ALU에 이어 Control Unit도 구현해 보았는데, 난이도가 점점 높아지고 있는 것을 실감했다. 수동으로 제어 신호(MI, RO, AO 등)를 켜서 RAM에서 레지스터로 값을 이동시키는 과정도 경험해 볼수 있었고, 기계어를 사람이 이해하기 쉽게 만든 어셈블리어와, 이를 기계어로 변환하는 어셈블러의 역할까지 학습해 봄으로써 하드웨어 수준의 명령어 실행 과정을 이해할 수 있었다. 🏷출처https://inf.run/y1hhdhttps://inf.run/7mNZ2https://inf.run/uHJ1a
cs
・
발자국
2025. 06. 07.
0
인프런 워밍업 클럽 스터디 4기 - CS 전공지식 > 컴퓨터 구조 2주차 미션
◼컴퓨터 구조 1. 다음 파일의 모든 연결을 터널로 대체해보세요. 2. 8비트 32입력 MUX를 제작해보세요. 3. 10비트 입력 두 개(A, B)를 계산하는 ALU 만들어보세요. 4. 32비트 RAM을 만들어보세요. 디코더와 MUX는 logisim 기본 내장된 걸 사용해도 좋습니다.
cs
・
미션
2025. 06. 06.
0
인프런 워밍업 클럽 스터디 4기 - CS 전공지식 > 2주차 발자국
◼만들면서 쉽게 배우는 컴퓨터 구조Section5) 컴퓨터의 기초가 되는 하드웨어 만들기 MUX (Multiplexer, 멀티플렉서)여러 입력 중 하나를 선택하여 출력으로 내보내는 장치데이터 선택기라고도 불림 1비트 2입력 MUXSelection 입력 값에 따라 A입력 또는 B입력을 선택하여 출력Selection이 0 → 입력 A 선택Selection이 1 → 입력 B 선택 8비트 4입력 MUX4개의 8비트 입력 중 하나를 선택하여 출력 2비트의 Selection 입력 사용 (00₂ ~ 11₂)00₂(0) → IN_0 출력01₂(1) → IN_1 출력10₂(2) → IN_2 출력11₂(3) → IN_3 출력 8비트 8입력 MUX8개의 8비트 입력 중 하나를 선택하여 출력3비트의 Selection 입력 사용 (000₂ ~ 111₂)000₂(0) → IN_0 출력001₂(1) → IN_1 출력010₂(2) → IN_2 출력011₂(3) → IN_3 출력100₂(4) → IN_4 출력101₂(5) → IN_5 출력110₂(6) → IN_6 출력111₂(7) → IN_7 출력 디코더 (Decoder)n비트 입력을 받아 2ⁿ개의 출력 중 하나만 활성화 시키는 장치Enable 입력을 통해 디코더 회로 전체의 작동 여부를 제어Enable이 0이면 모든 출력은 0 (비활성화 상태)Enable이 1일 때에는 입력값에 따라 하나의 출력을 활성화 4비트 디코더 (Decoder)4비트 입력 → 2^4 = 16개 출력 중 하나만 활성화RAM 구현시 활용 컨트롤 버퍼제어 신호에 따라 데이터를 흐르게 하거나 차단하는 버퍼 Section6) CPU 만들기: 산술논리연산장치 (ALU) 폰 노이만 구조 컴퓨터입출력 장치 (I/O Device)중앙 처리 장치 (CPU)제어 유닛 (Control Unit)산술 논리 연산 장치 (ALU)메모리 (RAM) → 위 세 가지 구성 요소로 컴퓨터가 구성됨 반가산기 (Half Adder)두 개의 1비트 입력을 더하여, 합(Sum)과 자리올림(Carry)을 계산하는 조합 논리 회로특징입력: A, B (1비트씩)출력: Sum[XOR로 구현], Carry[AND로 구현] (각 1비트)자리올림(Carry-In)을 처리하지 못함 → 이전 자리의 올림을 고려하지 않음 → '반쪽짜리 가산기’ (반가산기)라 불림 진리표 전가산기 (Full Adder)세 개의 1비트 입력(두 입력 + 이전 자리의 자리올림)을 더하여, 합(Sum)과 자리올림(Carry-Out)을 계산하는 조합 논리 회로.특징:입력: A, B, Carry-In (1비트씩)출력: Sum[반가산기 2개로 구현], Carry-Out[반가산기 2개+OR로 구현] (각 1비트)자리올림을 연속적으로 처리 가능진리표 산술 논리 연산 장치 (ALU: Arithmetic Logic Unit)컴퓨터의 핵심 연산 장치로, 산술 연산과 논리 연산을 수행한다.산술 연산 : 덧셈, 뺄셈, 증가, 감소, 곱셈, 나눗셈논리 연산 : AND, OR, NOT, XOR, NAND, NOR 등비교 연산 : ==, >, =, CPU 내부에 포함되어 있으며, 프로세서가 수행하는 계산의 대부분은 이 ALU를 통해 처리음수 표현시 2의 보수 사용 Section7) 메모리 만들기조합 논리 회로 (Combinational Logic Circuit)출력이 현재 입력에만 의존하는 회로상태를 기억하지 않음 (메모리 없음)예시: AND, OR, NOT, Half Adder, Full Adder, Multiplexer, Decoder, ALU 순차 논리 회로 (Sequential Logic Circuit)이전 입력에 대한 출력이 다시 입력으로 들어가는 회로이전 상태를 기억예시: SR Latch, D Latch, JK Latch, Flip-Flop, Register, RAM SR LatchSet(S)과 Reset(R) 입력을 갖는 기본 기억 회로특정 조건에서 출력 Q는 이전 상태를 유지Gated SR Latch는 Enable 신호가 1일 때만 동작 D LatchS, R을 하나의 입력 D로 통합한 형태Enable이 1일 때 D의 값을 Q에 저장 JK LatchSR Latch의 단점 (S=R=1일 때 불안정)을 개선J = Set, K = Reset 의미J=K=1이면 출력이 반전 (Toggle 동작)내부 딜레이가 있어 안정적인 동작 위해 Clock 필요 클럭과 플립플롭Clock : enable을 0과 1로 반복해서 바꿔주는 신호 (Hz 단위로 동작)Trigger클럭 신호 중에서 "입력을 출력으로 반영하는 순간"을 결정하는 방식종류Level Trigger: High/Low 상태에서 작동 → D LatchEdge Trigger: Rising/Falling 순간에 작동 → Flip-Flop 레지스터8비트 저장 장치 여러 개의 Latch 또는 Flip-Flop으로 구성Latch 또는 Flip-Flop : 1비트 저장장치 RAM (Random Access Memory)주소를 통해 원하는 데이터에 접근 가능한 메모리 실행 중의 데이터와 상태를 임시로 저장 Mission2)https://inf.run/iWGzi ◼ 그림으로 쉽게 배우는 자료구조와 알고리즘Section5) Red-Black 트리 Red-Black 트리이진 탐색 트리의 일종으로,데이터가 삽입되거나 삭제될때 트리의 균형을 자동으로 유지하는 균형 이진트리이다.트리의 높이를 제한해 모든 연산의 최악의 시간복잡도를 O(log n)으로 유지하는 것이 목적조건모든 노드는 빨간색 혹은 검정색루트 노드는 검은색모든 리프 노드는 검은색빨간색 노드의 자식은 검은색모든 리프 노드에서 Black Depth는 같다 Section6) 우선순위 큐와 힙 우선순위 큐데이터의 삽입 순서와는 상관 없이 우선순위가 높은 데이터가 먼저 나오는 큐 힙완전 이진 트리 형태의 자료구조로, 부모 노드가 자식보다 크면 최대 힙, 작으면 최소 힙을 의미 🗒회고MUX, 반가산기, 전가산기, 디코더, ALU 등 조합 논리 회로를 직접 구현해보며 각 장치의 동작 원리와 회로 구성 방식을 직관적으로 이해할 수 있었다.또한 Register와 RAM 같은 순차 논리 회로를 만들며, 클럭과 Enable, 기억 소자의 역할, 메모리 동작 방식도 자연스럽게 배울수 있었다.단순 이론을 넘어서 실제 회로 구조를 만들어 시각화 해보는 경험을 통해 컴퓨터 구조애 대한 이해력이 높아지고 있는것 같다. 🏷출처https://inf.run/y1hhdhttps://inf.run/7mNZ2https://inf.run/uHJ1ahttps://velog.io/@kku64r/rbtreehttps://suyeon96.tistory.com/31
cs
・
발자국
2025. 06. 01.
0
인프런 워밍업 클럽 스터디 4기 - CS 전공지식 > 컴퓨터 구조 1주차 미션
◼컴퓨터 구조 1. 4입력 AND, OR, NAND, NOR, XOR 연산의 진리표를 작성해보세요.AND : 모든 입력값이 1일때만 결과는 1OR : 입력값중 하나라도 1이라면 결과는 1NAND : AND의 반대, 모든 입력이 1일 때만 0, 나머지는 1NOR : OR의 반대, 모든 입력이 0일 때만 1, 나머지는 0XOR : 입력값 중 1의 개수가 홀수이면 1, 짝수이면 0 2. 다음 불 방정식들을 여러 방법을 이용해 간략화 해보세요.A( (BB)’+ 0A) + (CC)' = (AB’) +C(B’B’) + (AD’ + (CA)’)D = B’ + (DC’) + (DA’)(A’B) + B(B1 + BC) = B B’(1C + BD) + DB = (B’C) + (DB) 3. 다음 2진수를 10진수로 변환해보세요.1101112^5 + 2^4 + 0 + 2^2 + 2^1 + 2^032 + 16 + 4 + 2 + 155100000012^7 + 1 = 129111111000002^10 + 2^9 + 2^8 + 2^7 + 2^6 + 2^5 = 20161010102^5 + 2^3 + 2^5 = 32 + 8 + 2 = 42 4. 다음 10진수를 2진수로 변환해보세요.10 = 1010₂2 |10 2 | 5 - 0 2 | 2 - 1 | 1 - 0 27 = 11011₂2 |27 2 |13 - 1 2 | 6 - 1 2 | 3 - 0 | 1 - 1 86 = 1010110₂2 |86 2 |43 - 0 2 |21 - 1 2 |10 - 1 2 | 5 - 0 2 | 2 - 1 | 1 - 0 516 = 10000001002 |516 2 |258 - 0 2 |129 - 0 2 | 64 - 1 2 | 32 - 0 2 | 16 - 0 2 | 8 - 0 2 | 4 - 0 2 | 2 - 0 | 1 - 0 5. 다음 불 방정식을 logisim을 이용해 회로를 만들어보세요.(B’C) + (DB)B’C : NOT(B) AND C → AND 연산DB : D AND B → AND 연산전체: (B’C) + (DB) → OR 연산(AB’) +C AB’ : A AND NOT(B) → AND 연산+C : 결과와 C를 OR 연산 B’ + (DC’) + (DA’)B’ : NOT(B) → NOTDC’ : D AND NOT(C) → ANDDA’ : D AND NOT(A) → AND전체는 OR 연산
CS
・
미션
2025. 05. 31.
1
인프런 워밍업 클럽 스터디 4기 - CS 전공지식 > 1주차 발자국
◼만들면서 쉽게 배우는 컴퓨터 구조Section1) 컴퓨터 구조 개요컴퓨터는 트랜지스터라는 반도체 소자로 만들어지고, 여러 트랜지스터로 NAND 게이트를 만들며, 이로부터 컴퓨터가 구성된다. 프로그램의 동작방식 (2가지)컴파일러전체 코드를 미리 번역해 실행 속도가 빠름컴파일 시 문법 오류 사전 발견 가능인터프리터한 줄씩 번역하며 실행, 실행 중 문법 오류 가능실행 속도는 컴파일러보다 느림 Section2) 컴퓨터 구성 요소CPU컴퓨터의 두뇌 역할을 하는 장치로, 산술연산장치(ALU), 제어장치 등으로 구성된다. 메모리RAM, ROM, 캐시 메모리 등이 있다. 주변 장치입력 장치 (키보드, 마우스 등), 출력 장치 (모니터, 프린터 등) 등이 있다. 8비트, 32비트, 64비트 컴퓨터가 표현할수 있는 데이터 차이8비트: 2^8 = 256개32비트: 약 42억개 (RAM 4GB 한계)64비트: 약 18경개 (RAM 한계없음, 거의 무한대) Section3) 불 대수불 대수의 등장클로드 섀넌이 0과 1 (false, true)만으로 모든 논리 연산과 계이 가능함을 발견 주요 불 연산NOT: 입력의 반대값 출력AND: 둘 다 1일 때만 1 출력OR: 둘 중 하나 이상 1이면 1 출력NAND: AND의 결과를 반전NOR: OR의 결과를 반전XOR: 입력이 서로 다를 때 1 출력 (입력개수 2개일때), 1의 개수가 홀수이면 1, 아니면 0 (입력개수가 3개이상일때) 불 연산 우선순위 : NOT -> AND -> OR 불 대수의 성질과 법칙항등원 법칙, 교환법칙, 분배법칙, 동일법칙, 이중부정법칙, 흡수법칙, 드모르간 법칙 등이 있다 불 연산을 바탕으로 진리표 작성 가능방정식 -> 진리표 -> 논리회로로 변환 Section4) 비트10진법, 2진법, 16진법10진법은 0~9까지 10개의 숫자 사용2진법은 0과 1 두 가지 숫자만 사용16진법은 0~9, A~F(10~15)를 사용 바이트 저장 순서 방식리틀 엔디안: LSB(Least Significant Byte, 가장 낮은 자리 바이트)를 낮은 주소에 저장빅 엔디안: MSB(Most Significant Byte, 가장 높은 자리 바이트)를 낮은 주소에 저장 오버플로우표현할 수 있는 비트 수를 초과하는 계산 결과 발생 시 결과가 제대로 저장되지 못하는 현상 음수 표현MSB(Most Significant Bit, 최상위 비트)가 0이면 양수, 1이면 음수로 해석 2의 보수법음수를 표현하는 방법음수 = 1의 보수(모든 비트를 반전) + 1 Section5) 컴퓨터의 기초가 되는 하드웨어 만들기 Logisim-evolution 같은 시뮬레이터를 사용해 논리 회로를 직접 설계·실험 가능,설치하려면 JDK 필요, GitHub에서 최신 버전 다운로드 가 기본 논리 게이트NAND 게이트, NOT 게이트, AND 게이트, OR 게이트, XOR 게이트 Mission1)https://inf.run/wLEBH ◼그림으로 쉽개 배우는 자료구조와 알고리즘Section1) 개요선형 자료구조 : 배열, 연결 리스트, 스택, 큐비선형 자료구조: 트리, 그래프, 힙 P-NP 문제 개념 이해빅오 표기법 (시간 복잡도)결정 문제와 최적화 문제P 문제 (Polynomial time 문제)NP 문제 (Nondeterministic Polynomial time 문제)NP-hard 문제P vs NP 문제 Section2) 트리와 이진트리트리노드(Node)와 간선(Edge)으로 구성된 계층적 자료구조 트리의 구성요소노드, 간선, 루트 노드, 자식 노드, 형제 노드, 리프 노드, 레벨, 높이 이진트리각 노드가 최대 2개의 자식 노드를 갖는 트리포화이진트리와 완전이진트리도 존 Section3) 이진 탐색트리각 노드가 값의 기준점 역할을 하며, 찾고자 하는 값이 현재 노드의 값보다 크면 오른쪽 서브트리를, 작으면 왼쪽 서브트리를 탐색하는 구조 Section4) AVL 트리높이 균형을 유지하는 이진 탐색 트리로, 각 노드의 왼쪽과 오른쪽 서브트리 높이 차이(균형 인수)가 최대 1 이내여야 한다.이 균형 조건을 벗어나면 회전 연산을 통해 트리의 균형을 맞춰 탐색, 삽입, 삭제 수행 🗒회고컴퓨터 구조와 자료구조(알고리즘) 강의를 동시에 완벽히 이해하기엔 시간적으로 무리가 있을 것 같아 컴퓨터 구조 심화 학습에 좀 더 집중해볼 예정이다.강의에서 Logisim-evolution을 활용해 AND, OR, NOT, XOR 등의 게이트를 직접 만들어보는 과정이 인상 깊었다. 회로를 하나하나를 쌓아가며 구조를 이해하는게 재미가 있어 몰입이 잘 되었다.강의를 완강할 즈음에는, 정말 작은 컴퓨터 하나쯤은 스스로 만들어 낼 수 있을 것 같은 기대감이 든다 🏷출처https://inf.run/y1hhdhttps://inf.run/7mNZ2https://inf.run/uHJ1a
CS
・
발자국
2024. 10. 25.
0
인프런 워밍업 클럽 스터디 2기 - 백엔드 클린코드, 테스트코드 4주차 발자국
Section7) Mock을 마주하는 자세Test Double의 종류1) Dummy : 아무것도 하지 않는 깡통 객체2) Fake : 단순한 형태로 동일한 기능은 수행하나, 프로덕션에서 쓰기에는 부족한 객체 (ex, FakeRepository)3) Stub : 테스트에서 요청한 것에 대해 미리 준비한 결과를 제공하는 객체, 그 외에는 응답하지 않는다. //상태 검증 (State Verification)4) Spy : Stub이면서 호출된 내용을 기록하여 보여줄 수 있는 객체, 일부는 실제 객체처럼 동작시키고 일부만 Stubbing할 수 있다,5) Mock : 행위에 대한 기대를 명세하고, 그에 따라 동작하도록 만들어진 객체 //행위 검증 (Behavior Verification).BDDMockitoBDDMockito는 Mockito에서 BDD 스타일에 맞추어 모든것의 이름만 바꾼 것이다.일례로 given 구역에 .when()을 쓰면 이질감이 들기 떄문에 BDDMockito가 생긴 것이다..Classicist VS Mockist1) Classicist- 꼭 필요한 경우에만 mocking을 쓰고 왠만하면 진짜 객체로 테스트 하자는 주의이다.2) Mockist- 모든 것을 Mocking 위주로 하여 테스트 하자는 주의이다..Section8) 더 나은 테스트를 작성하기 위한 구체적 조언1) 한 문단에 한 주제!- DisplayName을 한 문장으로 구성할 수 있어야 한다~!2) 완벽하게 제어하기3) 테스트 환경의 독립성을 보장하자- 테스트에서는 팩토리 메서드를 지양하고 Buider나 생성자를 통해 최대한 독립성을 보장해서 given절을 구성하는게 좋다.4) 테스트 간 독립성을 보장하자- 테스트간의 공유자원 사용하지 않기.- 테스트간의 독립성 보장하기~!5) 한 눈에 들어오는 Test Fixture 구성하기- Fixture : 고정룰, 고정되어 있는 물체- Test Fixture : 테스트를 위해 원하는 상태로 고정시킨 일련의 객체6) Test Fixture 클렌징- @Transactional, @rollback 방식과 deleteAllInBatch(), deleteAll() 등을 잘 알고 사용해야 한다.7) @ParameterizedTest8) @DynamicTest9) 테스트 수행도 비용이다. 환경 통합하기- @DataJPATest 보다 @SpringbootTest 사용을 권장한다.- 컨트롤러(통합) 테스트시 @WebMvcTest의 Controllers 옵션을 통해 특정 컨트롤러들만 지정하여 테스트해줌으로써 테스트 수행 비용을 줄여준다.10) private 메서드는 테스트할 필요가 없다.11) 테스트에서만 필요한 메서드 중 생성자 등은 프로덕션 코드에 생성해도 좋다..Section9) AppendIx1) 학습 테스트- 잘 모르는 기능, 라이브러리, 프레임워크를 학습하기 위해 작성하는 테스트- 여러 테스트 케이스를 스스로 정의하고 검증하는 과정을 통해 보다 구체적인 동작과 기능을 학습할 수 있다.- 관련 문서만 읽는 것보다 훨씬 재미있게 학습할 수 있다.2) Spring Rest Docs- 테스트 코드를 통한 API 문서 자동화 도구- API 명세를 문서로 만들고 외부에 제공함으로써 협업을 원활하게 한다.- 장점→ 테스트를 통과해야 문서가 만들어진다 (신뢰도가 높다)→ 프로덕션 코드에 비침투적이다.- 단점→ 코드 양이 많다.→ 설정이 어렵다..Day-15 Mission) 레이어드 아키텍처에서의 테스트 코드 작성강의로 배운 레이어드 아키텍처 관련 내용을 확장시켜 정리할 수 있어 좋았다.과제 Link.Day-18 Mission) Test Double 어노테이션 이해 및 테스트 항목 배치@Mock, @MockBean, @Spy, @SpyBean, @InjectMocks의 차이점을 정리하고 given-when-then 전략으로 테스트 코드 배치 방법을 고민해 볼 수 있어 좋았다.과제 Link..회고오늘로써 인프런 워밍업 클럽 스터디 2기 대장정이 마무리 되었다.클린코드와 테스트코드는 누구나 중요성을 알지만, 혼자서 공부하기 쉽지 않은 부분이다.강의를 완벽하게 이해하지는 못했지만, 강의를 통해 Clean Code와 Test Code에 한 발자국 더 다가갈 수 있었고, 실무에도 점차적으로 적용 해보면서 뜻 깊은 경험을 할 수 있었다.다음에 인프런 스터디 3기가 열린다면 재참여를 고려해 봐야겠다마지막으로 강의와 스터디를 만들어주신 박우빈님과 스터디 관리에 힘써주신 셰리 매니저님께 감사의 마음을 전합니다..출처https://inf.run/zgJk5https://inf.run/kHiWM
백엔드
・
워밍업클럽
・
테스트코드
2024. 10. 19.
0
인프런 워밍업 클럽 스터디 2기 - 백엔드 클린코드, 테스트코드 3주차 발자국
3주차부터 Practical Testing (실용적인 테스트 가이드) 강의로 넘어가게 되었다. Section1) Intro강의에서 학습하게 될 것1) 테스트 코드가 필요한 이유2) 좋은 테스트 코드란?3) 실제 실무에서 진행하는 방식 그대로 테스트를 작성해가면서 API를 설계하고 개발하는 방법4) 정답은 없지만, 오답은 있다! 구체적인 이유에 근거한 상세한 테스트 작성 팁Section2) 테스트는 왜 필요할까?1) 테스트는 왜 필요할까?- 테스트 코드를 작성하지 않는다면 코드의 변화가 생기는 매 순간마다 발생할 수 있는 모든 Case를 고려해야 한다..2) 테스트 코드가 병목이 된다면?- 테스트코드 자체가 유지보수하기 어려워진다.- 잘못된 검증이 이루어질 가능성이 생긴다..3) 올바른 테스트 코드는?- 자동화 테스트로 비교적 빠른 시간 안에 버그를 발견할수 있고, 수동 테스트에 드는 비용을 크게 절약할 수 있다. Section3) 단위 테스트Junit5로 테스트하기1) 단위 테스트- 작은 (ex, 클래스 or 메서드) 코드 단위를 독립적으로 검증하는 테스트- 검증속도가 빠르고, 안정적이다.2) Junit5- 단위 테스트를 위한 테스트 프레임워크- XUnit - Kent Back, - Sunit (Samltalk), Junit(Java), NUnit(.NET)- Spring-boot-starter-test 라이브러리를 통해 사용 가능하다..3) AssertJ- 테스트코드 작성을 원활하게 돕는 테스트 라이브러리- 풍부한 API, 메서드 체이닝 지원- Spring-boot-starter-test 라이브러리를 통해 사용 가능하다.테스트 케이스 세분화1) 해피 케이스- 요구사항을 그대로 만족하는 케이스- 경계값 테스트 : 범위 (이상, 이하, 초과, 미만), 구간, 날짜 등이 중요.2) 예외 케이스- 경계값 테스트 : 범위 (이상, 이하, 초과, 미만), 구간, 날짜 등이 중요.테스트하기 어려운 영역 분리하기1) 테스트하기 어려운 영역- 관측할때마다 다른 값에 의존하는 코드→ 현재 날짜/시간, 랜덤 값, 전역변수/함수, 사용자 입력 등- 외부 세계에 영향을 주는 코드→ 표준 출력, 메시지 발송, 데이터베이스에 기록하기 등.2) 순수 함수 - 테스트하기 쉬운 코드- 같은 입력에는 항상 같은 결과- 외부 세상과 단절된 형태- 테스트하기 쉬운 코드 Section4) TDDTDD (Test Driven Development)1) TDD- 프로덕션 코드보다 테스트 코드를 먼저 작성하여 테스트가 구현 과정을 주도하도록 하는 방법론.2) TDD의 핵심 가치- 기존) 선 기능 구현, 후 테스트 작성의 문제점→ 테스트 자체의 누락 가능성→ 특정 테스트(==해피 케이스) 케이스만 검증할 가능성→ 잘못된 구현을 다소 늦게 발견할 가능성- TDD) 선 테스트 작성, 후 기능 구현→ 복잡도가 낮은(==유연하며 유지보수가 쉬운), 테스트 가능한 코드로 구현할 수 있게 한다.→ 쉽게 발견하기 어려운 엣지(Edge) 케이스를 놓치지 않게 해준다.→ 구현에 대한 빠른 피드백을 받을 수 있다.→ 과감한 리팩토링이 가능해진다.Section5) 테스트는 [문서]다테스트는 [문서]다1) 테스트 == 문서- 프로덕션 기능을 설명하는 테스트 코드 문서- 다양한 테스트 케이스를 통해 프로덕션 코드를 이해하는 시각과 관점을 보완- 어느 한 사람이 과거에 경험했던 고민의 결과물을 팀 차원으로 승격시켜서, 모두의 자산으로 공유.DisplayName을 섬세하게1) DisplayNamed을 섬세하게 적기- 메서드 자체의 관점보다 도메인 정책 관점으로, 도메인 용어를 사용하여 한층 추상화된 내용을 담기- 테스트의 현상(ex, 성공한다… 실패한다 등)을 중점으로 기술하지 말 것.BDD 스타일로 작성하기1) BDD (Behavior Driven Development)- TDD에서 파생된 개발 방법으로- 함수 단위의 테스트에 집중하기보다, 시나리오에 기반한 테스트케이스(TC) 자체에 집중하여 테스트하는 기법- Given / When / Then 방식 사용→ Given : 시나리오 진행에 필요한 모든 준비 과정 (객체, 값, 상태 등)→ When : 시나리오 행동 진행→ Then : 시나리오 진행에 대한 결과 명시, 검증.Mission 12) 단위 테스트 작성studycafe 프로젝트에서 InputHandler, StudyCafePassOrder, StudyCafeSeatPass 클래스에 대한 테스트 코드를 작성하였다.고민했던 점으로는 Scanner를 통해 사용자 입력을 받는 로직을 테스트하기 위해 Mock을 사용할 수 있지만, Mock 대신 InputStream과 System.setIn()을 통해 입력해주는 방식을 선택했다.작은 메서드 단위로 단위 테스트를 진행하니 코드도 복잡해지지 않고 간결하여 테스트 하기가 수월하였다.Github Code. Section6) Spring & JPA 기반 테스트레이어드 아키텍처(Layered Architecture)1) Layered Architecture- Presentation Layer, Business Layer, Persistence Layer로 구분- 아키텍처를 분리하는 이유 : 관심사의 분리.Spring / JPA 훑어보기 & 기본 엔티티 설계1) Library vs Framework- Library : 외부에서 이미 개발된 코드를 가져온다. (내 코드가 주체가 되어 동작)- Framework : 이미 동작하는 환경이 구성되어 있고, 내 코드는 프레임안에서 수동적으로 동작.2) Spring- IoC (inversion of Control) : 객체의 생성과 의존성 관리를 프레임워크에서 대신 수행- DI (Dependency Injection) : 외부에서 객체 간의 의존성 주입을 통해 결합도를 낮춰줌- AOP (Aspect Oriented Programming) : 공통 관심사를 별도의 로직으로 분리해 코드 중복을 줄여주고 모듈화.3) JPA- Java Persistance API- Java 진영의 ORM 기술 표준 - 반복적인 CRUD SQL을 생성 및 실행해주고, 여러 부가 기능들을 제공- Spring 진영에서는 JPA를 한번 더 추상화한 Spring Data JPA 제공- 주로 사용되는 어노테이션들→ @Entity, @Id, @Column→ @ManyToOne, @OneToMany, @OneToOne, @ManyToMany .Layer별 테스트1) Persistence Layer- Data Access의 역할- 비즈니스 가공 로직이 포함되어서는 안됨, Data에 대한 CURD에만 집중한 레이어.2) Business Layer- 비즈니스 로직을 구현하는 역할- Persistence Layer와의 상호작용(Data를 읽고 쓰는 행위)를 통해 비즈니스 로직을 전개- 트랜잭션을 보장.3) Presentation Layer- 외부 세계의 요청을 가장 먼저 받는 계층- 파라미터에 대한 최소한의 검증을 수행.회고- 테스트 코드 작성을 의무적으로 작성 하지 않는 환경에서 일을 해왔는데, 스터디를 진행하면서 단위 테스트 코드 작성의 중요성과 필요성을 깨달았다. 모든 예외 케이스를 조기에 발견해서 대처할 순 없겠지만 내가 작성한 코드 범위내에서 테스트가 필요한 영역들을 분리하여 로직이 의도한 대로 동작하는지 검증하는 작업은 백엔드 개발자의 숙명이라는 생각이 들었다.이제 Mock과 테스트 방법론에 대한 강의가 남아있는데, 마지막 주차도 지금처럼 묵묵히 학습해 나갈 것이다.출처https://inf.run/zgJk5https://inf.run/kHiWM
백엔드
・
워밍업클럽
・
테스트코드
2024. 10. 12.
0
인프런 워밍업 클럽 스터디 2기 - 백엔드 클린코드, 테스트코드 2주차 발자국
강의 수강 Section6) 코드 다듬기좋은 주석인란? -우리가 가진 모든 표현 방법을 총동원해 코드에 의도를 녹여냈음에도 불구하고 전달해야할 정보가 남았을때 주석을 사용해야 함. 주석을 사용하면 코드가 아닌 주석에 의존한다는 것을 알아야 함 변수와 메서드의 나열 순서- 변수는 사용하는 순서대로 나열- 메서드는 1순위가 공개 메서드, 2순위가 비공개 메서드 순으로 나열 Intellij IDE 활용- 코드 포맷 정렬 단축키 : Ctrl + ALT + L- Sonarlint : 오류, 버그, 스타일 등을 알려주어 문제점 개선을 도와주는 Plugin- .editorConfig : 확장자마다 스타일을 다르게 줄수 있게 도와주는 설정파일 Section7) 리팩토링 연습리팩토링 포인트- 추상화 레벨 : 중복 제거, 메서드 추출, 객체에 메시지 보내기- 객체의 책임과 응집도 : IO 통합, 일급 컬렉션, display()의 책임, Order 객체- 관점의 차이로 달라지는 추상화 : 구현에 초점을 맞춘 추상화 VS 도메인 개념에 초점을 맞춘 추상화 Section8) 기억하면 좋은 조언들능동적 읽기- 복잡하거나 엉망인 코드를 읽고 이해하려 할때, 리팩토링하면서 읽기-> 공백으로 단락 구분-> 주석으로 이해한 내용 표기하며 읽기-> 메서드와 객체로 추상화 해보기- 핵심 목표는 우리의 도메인 지식을 늘리는 것이고, 이전 작성자의 의도를 파악하는 것.2. 오버 엔지니어링- 필요한 적정 수준보다 더 높은 수준의 엔지니어링을 말함-> ex) 구현체가 하나인 인터페이스 : 구현체를 수정할 때마다 인터페이스도 수정해야 함.-> ex) 너무 이른 추상화 : 정보가 숨겨지기 때문에 복잡도가 높아지고, 후대 개발자들이 선대의 의도를 파악하기가 어려움 3. 은탄환은 없다- 항상 정답인 기술은 없음.- 오버 엔지니어링이 되더라도 한계까지 리팩토링 연습을 해보고, 적정 수준, 적정 시점을 깨닫기가 필요. 회고)2주차까지 쉼 없이 달려왔는데, readable code 강의가 끝난것이 끝이 아니라, 새로운 시작인 것 같다.이 강의를 통해 클린코드로 가는 발검을을 한 발자국 내딛은것 같다. 클린코드 책도 한번 읽어봐야 겠다는 생각도 들었다.3주차부터 Practical Testing 강의가 시작되는데, 테스트 코드 강의도 빠짐없이 수강하여 포기하지 않고 스터디를 끝까지 이어 나갈 것이다. 미션Day7-Mission3) '스터디 카페 이용권 선택 시스템' 프로젝트 리팩토링리팩토링 진행 내용코드 중복 제거- if문 내에 중복된 지역 범위 코드들을 전역화메서드로 추출- 동일한 맥락의 코드들을 메서드화NullPointException 방지 - Null 값 처리를 위한 Optional 사용메서드 오버로딩 추가 - Null 매개변수 사용을 외부에 드러내지 않기 위해 메서드를 오버로딩하여 사용Github Code 회고- 추상화 관점에서의 리팩토링을 어느정도 진행하였는데, 객체의 책임과 응집도 관점에서 좀 더 리팩토링을 진행해야 겠다는 생각과 함께 리팩토링에는 끝이 없다는 것을 느끼고 있다. 어쩌면 내가 진행한 readable한 code가 관점에 따라 누군가에게는 그렇지 않을수도 있다는 생각이 든다. 출처https://inf.run/zgJk5https://inf.run/kHiWM
백엔드
・
워밍업클럽
・
클린코드
2024. 10. 05.
0
인프런 워밍업 클럽 스터디 2기 - 백엔드 클린코드, 테스트코드 1주차 발자국
Section2) 추상Clean Code를 추구해야 하는 이유나를 포함해 다른 개발자가 코드를 읽고 이해하는데 드는 시간이 절약된다.프로그램의 정의프로그램 = (데이터가 담긴) 변수 + (변수를 사용하는) 메서드의 집합추상중요한 정보는 가려내어 남기고, 덜 중요한 정보는 생략하여 버리는 것적절한 추상화 : 도메인 안에서, 정말 중요한 핵심 개념만 남겨서 표현하는 것이다.추상화의 가장 대표적인 행위는 이름을 짓는 것이다.(변수) 이름 짓기 Tip1) 단수와 복수 구분- 끝에 '(e)s'를 붙여 구분2) 이름 줄이지 않기- 일반적으로 무엇이든 이름을 줄여서 사용하는 것은 가독성을 제물로 바쳐 효율성을 얻는 것인데,유지보수 관점에서 득보다 실이 크다.- 관용어 처럼 자주 사용하는 것은 줄여도 괜찮다.=> ex, column -> col, latitude -> lat=> count -> cnt (추천X)3) 은어/방언 사용X- 현재의 팀만 아는 용어 사용 금지4) 좋은 코드를 보고 습득하기메서드와 추상화한 메서드는 반드시 한가지 일만 해야 한다.2가지 일을 하게된다면 추상화된 내용(==메서드 선언부)을 보고 구체적인 내용(메서드 구현부)의 유추가 어렵다.추상화 레벨외부 세계(==추상화 레벨이 높은 세게)와 내부세계(==추상화 레벨이 낮은 구체)를 나누었을때 추상화 레벨이 달라지는데, 하나의 세계 안에서 각 로직의 추상화 레벨은 동등해야 한다.매직 넘버, 매직 스트링매직 넘버(스트링) : 의미를 갖고 있으나, 상수로 추출되지 않은 숫자, 문자열 등을 말한다.Mission 1) 생각나는 추상과 구체의 예시Execute Login1) 클라이언트가 서버에 암호화된 ID와 Password를 HTTP Body에 담아 Request를 보낸다.2) 서버는 ID와 Password를 복호화하고 각 필드에 대한 유효성 검사를 한다.3) 유효하다면, 복호화된 ID와 Password를 DB에 보내 가입된 유저인지 확인한다.4) 가입된 유저라면, Session Cookie 혹은 JWT 등에 사용자 정보를 담아 클라이언트에 Response로 보낸다.Section3) 논리, 사고의 흐름뇌 메모리 적게 쓰기최소의 인지적 노력으로 (뇌 메모리를 줄여) 최대의 정보를 제공해야 한다,Early returnelse (if) 대신 return을 사용하는 것을 권장한다,.사고의 Depth 줄이기1) 중첩 반복문을 메서드 혹은 Stream을 통해 개선하면 좋다.2) 사용할 변수는 가깝게 선언하기공백라인도 의미를 가진다.부정어if문에서 부정어(!) 사용시 메서드화하여 분리하기해피케이스와 예외처리1) 예외가 발생할 가능성을 낮추는게 좋다. (ex, 사용자 입력, 객체 생성자, 외부 서버의 요청 등)2) 의도한 예외(ex, Custom Exception)와 예상하지 못한 예외 구분하기3) NullPointException은 항상 발생하지 않게 해야 한다.- 메서드 설계시 return null을 자제하고, Optional 사용을 고려하기 - Optional의 orElse(), orElsGet(), orElseThrow() 메서드의 차이 이해 필요.Section4) 객체지향 패러다임객체 설계1) 새로운 객체 생성시 주의사항- 1개의 관심사로 명확하게 책임이 정의되었는지 확인 필요- 생성자, 정적 팩토리 메서드에서 유효성 검증이 가능함을 인지- setter 사용 자제- getter도 사용 자제하고, 반드시 필요한 경우에만 추가 - 필드의 수는 적을수록 좋다2) 도메인 지식은 만드는 것이 아니라 발견하는 것Mission 2-1) 읽기 좋은 코드로 리팩토링#중요하게 생각한 점1) order 객체 Null 체크 필요2) if-else문들 if문으로 개선3) 부정어구(!) 없애기4) getter 제거 → 객체에 의미가 담긴 메서드를 별도 생성5) 공백라인 사용public boolean validateOrder(Order order) { //1) Null Check if (order == null) { log.info("주문을 확인할 수 없습니다."); return false; } //2) remove (getter) if (order.hasNoItems()) { log.info("주문 항목이 없습니다."); return false; } //3) remove (! + if-else + getter) if (order.isInvalidTotalPrice()) { log.info("올바르지 않은 총 가격입니다."); return false; } //4) remove (! + if-else) if (order.hasNoCustomerInfo()) { log.info("사용자 정보가 없습니다."); return false } return true; } public class Order { private List items; private double totalPrice; private CustomerInfo customerInfo; public boolean hasNoItems() { return items == null || items.isEmpty(); } public boolean isInvalidTotalPrice() { return totalPrice Mission 2-2) 자기만의 언어로 정리한 SOLID1) SRP- Single Responsibility Principle (단일 책임의 원칙)- “하나의 클래스에 변경이 발생한다면 그 이유(==책임)는 반드시 하나여야 한다”는 원칙- ex) 프로그램 실행 부와 실제 실행 로직은 나누어져 있어야 한다.- 높은 응집도, 낮은 결합도와 관련 있음.2) OCP- Open-Closed Principle (개방-폐쇄 원칙)- “기존 코드의 변경 없이, 기능을 확장할 수 있어야 한다”는 원칙3) LSP- Liskov Substitution Principle (리스코프 치환 원칙)- 상속 구조에서, “부모 클래스의 인스턴스는 자식 클래스의 인스턴스로 치환될수 있어야 한다”는 원칙 4) ISP- Interrface Segregation Principle (인터페이스 분리 원칙)- ”하나의 구체 클래스는 자신이 사용하지 않는 인터페이스에 의존해서는 안된다”는 원칙(이때는, 인터페이스를 2개로 분리해야 한다) 5) DIP- Dependency Inversion Principle (의존성 역전 법칙)- “레벨이 높은 모듈(ex, Lv2 카페)은 구체 모듈(ex, Lv0 커피)에 바로 의존해서는 안되고 추상화(ex, Lv1 음료)에 의존해야 한다”는 원칙 미션을 통해 SOLID 원칙을 다시 한번 상기시킬수 있었는데, 실제 업무에 활용하기 위해서는 스스로 좀더 깊은 학습이 필요할것 같다. 그리고 클린코드의 방법론을 미션을 통해 적용해 보면서 코드가 좀 더 잘 읽히고 이해하기 쉬워지는 것을 직접 느낄수 있었다.Section5) 객체지향 적용하기상속과 조합상속은 시멘트처럼 굳어지는 구조이기 때문에 수정이 어려우므로, 상속보다 조합을 사용하는게 좋다.Value Object도메인의 어떤 개념을 추상화하여 표현한 값 객체로, 불변성, 동등성, 유효성 검증 등을 보장해야 한다.VO (Value Object)는 내부의 모든 값이 다 같아야 동등한 객체로 취급한다. 이에 반해 Entity는 식별자만 같으면 동등한 객체로 취급한다.일급 컬렉션컬렉션(List, Set, Map 등)을 포장하면서, 컬렉션만을 유일하게 필드로 가지는 객체로, 단 하나의 컬렉션 필드만을 가진다.만약, getter로 컬렉션을 반환할 일이 생긴다면 외부 조작을 피하기 위해 꼭 새로운 컬렉션(List)으로 만들어 반환하는게 좋다. 스터디를 진행하면서, 처음에는 완벽하게 다 이해하려고 생각해 학습에 시간이 오래걸렸는데, 이제는 내가 당장 적용해 볼수 있는 부분들을 Target으로 하여 배워나가야 겠다는 깨달음을 얻었다. 출처https://inf.run/zgJk5https://inf.run/kHiWM
백엔드
・
워밍업클럽
・
클린코드