블로그

워밍업 클럽 4기 백엔드 - 3주차 발자국

3주차 회고✅ 미션 회고테스트 코드를 직접 작성해보는 과제가 주어졌다. 막상 손으로 써보니 예상보다 고민할 포인트들이 많았다. 테스트 설명을 어떻게 일관성 있게 작성할지, 테스트 단위의 크기를 어떻게 잡을지 등 단순히 "돌아가는 테스트를 만든다"는 차원을 넘는 고민들이 생겼다. 테스트를 작성하지 않았다면 미처 떠올리지 못했을 다양한 관점들을 경험할 수 있었던 좋은 기회였다.✅ 강의 회고스프링을 활용해서 간단한 기능들을 직접 만들어보고, 이에 대한 테스트를 TDD 방식으로 구현해 나가는 과정이 인상 깊었다. 테스트 코드 자체에 대한 설명도 좋았지만, 실무에서 마주칠 수 있는 동시성 이슈나 리팩토링 전략, 패키지 구조 같은 부분까지 언급해주셔서 실전 감각을 익히는 데 도움이 됐다. 무엇보다, 단순히 ‘이렇게 한다’가 아니라 ‘왜 이렇게 해야 하는지’를 같이 짚어줘서 더 깊이 있게 이해할 수 있었던 것 같다.✅ 학습 내용 요약Persistence Layer: CRUD에 집중, 비즈니스 로직 XBusiness Layer: 핵심 로직 구현, 트랜잭션 보장Presentation Layer: 요청 처리, 파라미터 최소 검증✅ 느낀 점늘 테스트 코드에 대한 부담감이 있었는데, 직접 TDD 방식으로 작성해보니 생각보다 자연스럽게 코드가 작성됐다. 이전에는 주로 비즈니스 로직에만 테스트를 작성했지만, 이번 기회를 통해 각 레이어 별로 테스트를 어떻게 구성해야 하는지도 알게 되었다. 특히 @DataJpaTest와 @SpringBootTest의 차이점처럼 기술적인 디테일을 짚어준 것도 좋았고, 지금 당장은 직접 적용하지 못하더라도 ‘이런 상황에서는 이런 고민을 할 수 있겠구나’ 하고 한 번 더 생각해볼 수 있는 포인트들을 많이 얻었다. 단순한 기능 구현을 넘어 코드의 구조나 품질을 고민하게 되는 계기가 됐다.(Practical Testing: 실용적인 테스트 가이드)

백엔드백엔드

[워밍업클럽 4기-DevOps] 3주차 발자국

데브옵스 실습 회고 - 배포 자동화의 흐름을 타다이번 주차는 DevOps의 실제 흐름을 따라가 보면서, 단순한 이론이 아닌 도구 중심의 실습 경험을 쌓을 수 있었다. DevOps 개념 다시 보기DevOps는 단순히 도구 조합이 아니라, 코드를 빌드해서 실행 가능한 파일을 만든다는 공통된 흐름이 있다는 걸 실습을 통해 몸으로 느꼈다.또한, DevOps 외에도 다양한 ~Ops 용어들을 접하며 시스템 운영의 폭넓은 영역도 엿볼 수 있었다. Jenkins로 DevOps 흐름 만들기Jenkins를 띄워서 글로벌한 빌드 환경을 구성GitHub에 있는 소스를 Jenkins가 빌드빌드된 결과를 K8s에 배포단순히 버튼 몇 번 누르는 자동화가 아니라, 실제로 배포 흐름을 직접 구성해보니 전체 과정이 훨씬 선명해졌다.배포 전략: Blue/Green과 CanaryKubernetes 기본 배포 방식이 아니라, Blue/Green과 Canary 전략을 적용해보면서어떤 상황에 어떤 방식이 적절한지각 전략의 장단점은 무엇인지명확하게 정리할 수 있었다.앞으로 프로젝트 배포 시 고려해야 할 실전 감각을 익혔다.Jenkins 파이프라인 + 배포 자동화Jenkins Pipeline을 통해 작업 흐름을 시각적으로 파악kubectl create, apply, patch 명령어 차이 실습Label과 Selector를 이용한 Blue/Green 트래픽 전환 구현→ Green 상태 확인 후 Blue 제거 or 롤백까지 직접 수행Helm, 아직은 낯설지만 가능성은 큼Helm은 분명 강력한 툴인데, 아직 손에 익지 않아 불편함도 느껴졌다.하지만 익숙해지면 배포 생산성이 급격히 올라갈 것 같은 기대감도 든다.기본 YAML부터 정확히 구성하는 습관이 결국 Helm으로 이어진다는 점도 기억할 부분이다.

워밍업 클럽 4기 BE - 3주차 발자국

3주차 미션 회고토이 프로젝트에서 직접 테스트 코드를 작성하면서, 예상보다 다양한 부분에서 고민할 지점들이 생겼다. 테스트 설명을 일관되게 유지하는 방법부터, 하나의 테스트 단위를 어떤 크기로 설정할지까지 여러 가지를 고민하게 됐다. 직접 테스트를 작성하지 않았다면 떠올리지 못했을 다양한 관점들을 생각해볼 수 있는 좋은 기회였다. 3주차 강의 회고스프링을 활용해 간단한 서비스를 직접 만들어보고, 각 기능에 맞는 테스트 코드를 작성해 나가는 과정을 통해 많은 것을 배울 수 있었다. 테스트 코드 작성뿐만 아니라, 잠시 잊고 지냈던 스프링과 JPA 관련 트러블슈팅부터 아키텍처에 대한 관점, 패키지 구조에 대한 인사이트까지 얻을 수 있었던 유의미한 시간이었다. 3주차 학습 내용 요약Persistence LayerData Access의 역할 비지니스 가공 로직이 포함되어서는 안된다. Data에 대한 CRUD에만 집중한 레이어Business Layer비지니스 로직을 구현하는 역할Persistence Layer와의 상호작용을 통해 비지니스 로직을 전개시킨다. 트랜잭션을 보장해야 한다. Presentation Layer외부 세계의 요청을 가장 먼저 받는 계층 파라미터에 대한 최소한의 검증을 수행한다.주요 인사이트 1섹션명 : Business Layer 테스트 (2)타임블록 : 11:10 ~ 12:00내용 : @DataJpaTest와 @SpringBootTest주요 인사이트 2섹션명 : Business Layer 테스트 (3)타임블록 : 31:00 ~ 32:00내용 : 여러 계층에서 생기는 중복 벨리데이션에 대한 고찰주요 인사이트 3섹션명 : Business Layer 테스트 (3)타임블록 : 46:00 ~ 47:00내용 : 테스트 코드의 @Transaction 사용 시 주의사항

[ 인프런 워밍업 클럽 4기 Devops ] 3 주 차 발자국 (13일의 금요일 -안상민)

월 - 데브옵스 한방 정리화 - 손쉽게 데브옵스 환경을 구축하는 방법수 - 배포를 시작하기 전에 반드시 알아야 할 것들목 - Jenkins Pipeline (기초부터 Blue/Green 까지)A금 - Helm과 Kustomize 비교하며 사용-1 칭찬하고 싶은 점좋은 선생님을 만나 아직은 끝나진 않았지만 잘 마무리 할 수 있을것 같다는 느낌이 듭니다! 마라톤을 빗대어 말하자면 좋은 페이스 메이커가 만들어준 러닝 페이스를 잘 따라가고 있다는 생각이 들어 보람도 있고 잘하고 있다고 칭찬을 하고 싶네요.  아쉬웠던 점취준하면서 알바 하며 생활비를 충당하고 있는데 이번주에는 다음주 것 까지 마무리 지어 놓으려고 했었습니다만 못한것이 아쉽습니다. 그리고 이미 레퍼런스가 카페에 있는데 찾아 보지 않고 리눅스 커널이 뻗어버리는 버그를 혼자힘으로 해결 해보겠다고 이틀을 보낸게 영 도움이 되지 않은건 아니지만 시간을 잘 활용해서 쓰지 못했다는 생각이 들어 좀 아쉽네요. 보안해야 될 점버그나 에러가 발생했을 때 보통 수강생분들 환경에서 일어 나 듯이 우선 관련되어 있는 그룹에서 케이스를 찾아보거나 해당 커뮤니티에서 도움을 요청하려 합니다.  회고 저는 서른 초반입니다. 25세 때 처음으로 하프 마라톤을 해본적이 있습니다. 끝까지 완주해본 기억이 너무 뿌듯해서 아직까지 그 추억이 좋아서 지금까지 러닝을 해왔는데요. 일프로 강사님도 러너이시고 마라톤을 하신다고 하셔서 단방향이지만 그 이야기를 듣고 무척 내적 친밀감이 들었습니다.  그리고 이번 주를 회고를 하자면 벌써 이 과정도 75 프로나 왔네요.블로깅은 IT 업계를 들어오고 나서 복습이나 트러블 슈팅할 때 마다 정리해서 블로그 글로 게시하는 습관이 우리의 실력을 쌓는다고 종종 들어왔습니다.다음에 쓰일 때가 되서 까먹었다고 할지라도 아카이브 처럼 언제든지 쉽게 찾아 볼 수 있어서. 빠르게 다시 습득 할 수 있다고 귀에 익히 들어서 시작했지만 몇 일 못가고 지속하지 못한 기억들이 꽤 있는데,귀찮으면 잘 하지 않는 나를 잘아시는지 이번에 다시 그 중요성을 상기 시켜 주셔서 다시 블로그에 복습 글을 올리기 시작했습니다. 지인 추천을 받아 시작한 이 과정을 마라톤에 대입 해보자면 마치 페이스 메이커분을 잘 만났다는 생각이 듭니다. 좀 힘들어할 때 즈음 격려의 메세지로 힘을 주시는 것이 마라톤 대회 때 화이팅이라고 외쳐주시는 같은 마라톤 참가자 분들 서포터 분 처럼 많은 도움이 되었습니다. 마라톤이 장거리 스포츠인 만큼 전략도 필요한데 초반에 무리해서 달리면 후반가서 달리기 힘든데 이번주 수업도 추천해주시는 전략도 참 유익했던것 같습니다. DevOps 파이프 라인 수업도 1~4단계로 나눠서 처음부터 점점 복잡한 레벨로 올라가는 것이 처음 부터 뛰기 힘든 강도로 뛰는게 아니라 차근차근 천천히 뛰기 시작해서 점점 강도를 올리기는거 처럼 IT업계의 커리어도 안정적으로 늘려 나아가는데 있어 가장 좋은 방법론 이라 생각이 들었습니다.  남은 한주 마지막까지 화이팅 입니다! ※ 배운 내용 정리   

데브옵스 · 인프라쿠버네티스어너더클래스3주차회고

강동훈

[인프런 워밍업 클럽 4기 - CS] - 3주차 발자국

📕 자료구조와 알고리즘(심화)✅ 트라이와 자동완성📌 개념자동완성 기능을 구현할 수 있는 최적의 자료구조retrieval에서 유래되었다.이진트리는 아니라 자식 노드의 개수 제한이 없음저장하려는 단어를 한 글자씩 저장해서 key엔 글자, value에는 자식 노드를 저장한다.📌 성능해시테이블 검색 시간 복잡도 = O(1)트라이 시간 복잡도 = O(k) - 트라이에 저장된 노드 수에 따라 다름✅ 그래프📌 개념트리는 그래프의 종류 중 하나이다. 트리는 그래프이지만 그래프는 트리가 아니다.트리노드는 부모와 자식으로 계층적 구조를 가지며그래프에서 사이클이 없어야 한다.연결되지 않는 노드가 있으면 안된다.용어정점: 노드간선: 노드를 연결하는 선인접(adjacent): 간선으로 연결된 정점이웃(neighbor): 인접한 정점a와 b는 인접해있으며 a는 b의 이웃이며 b는 a의 이웃이다.방향 그래프: 양방향으로 간선의 방향이 정해져있음무방향 그래프: 간선의 방향이 없음 📌 깊이 우선 탐색 알고리즘(DFS)방문한 정점을 해시 테이블에 저장한다.사이클이 있는 경우 무한 루프에 걸릴 수 있음1. 현재 정점을 해시테이블에 방문한 정점으로 저장2. 현재 정점의 인접 정점들을 순회 (방문한 정점이라면 순회하지 않는다)3. 방문하지 않은 정점이면 재귀적으로 깊이 우선 탐색 수행📌 너비 우선 탐색 알고리즘(BFS)1. 방문한 정점을 저장하고 큐에 삽입2. 큐에 dequeue3. dequeue한 인접 정점을 순회한다1. 이미 방문한 정점이라면 건너뛰고2. 방문하지 않은 경우 첫 번째 경우 반복📌 DFS vs BFSDFS는 깊이를 우선 탐색BFS는 너비를 우선 탐색상황에 맞게 적절하게 사용하는 것친구 추천을 제공: 너비 우선 탐색 사용특정 지인을 찾는 경우: 깊이 우선 탐색 사용성능그래프의 성능은 정점 뿐만 아니라 간선에 따라서도 달라질 수 있다.O(V + E)V: 정점E: 간선 ✅ 가중 그래프📌 개념간선의 크기를 저장한다.- 크기는 사용자가 정하기 나름(정점 간의 거리나 비용이 될 수 있음)간선은 방향도 있으며 방향에 따라 가중치가 달리질 수도 있음 📌 다익스트라 알고리즘최적의 경로를 찾을 때 최적의 알고리즘1. shorted_path_table에 목표 정점과 거리를 초기화2. visited와 unvisited 배열로 구분3. unvisited에서 차례로 visited로 이동하면서 표 업데이트1. 인접도시의 거리들을 shorted_path_table에 저장하고2. 가까운 거리의 정점을 선택하여 visited로 이동3. 표의 값 + 인접 도시 거리 > 표의 값이면 표 수정 X ✅ 알고리즘📌 탐욕 알고리즘최적해를 구하는데 사용되는 근사적인 방법최적해를 구하는 보장은 없지만 단순하게 구할 수 있음매 선택지에서 가장 좋은 선택을 고름조건1. 탐욕스러운 선택 속성1. 앞의 선택이 이후의 선택에 영향을 주지 않음2. 최적 부분 구조 조건1. 문제에 대한 최적해는 부분에 대해서도 최적해이다=> '매트로이드' 📌 최소 신장 트리신장 트리그래프에 순환 구조없이 모든 정점이 연결되어 있음최소 신장 트리: 간선의 길이가 가장 짧은 신장 트리1. 크루스칼 알고리즘2. 프림 알고리즘1. 다익스트라 알고리즘과 비슷2. 최소 비용으로 연결3. 무방향 그래프에서 동작 📌 최대 유량 문제(Network Flow)용량이 다른 여러 상수관을 통해 Source에서 Sink까지 최대한 많은 양의 물을 보내는 문제1. 용량(Capacity): 한 상수관에 최대한 흐를 수 있는 물의 양2. 유량(Flow): 현재 상수관에 흐르고 있는 물의 양3. 잔여 용량 = 용량 - 유량탐색 알고리즘1. 포드 폴커슨 알고리즘: DFS1. Source에서 Sink로 가는 경로 하나를 DFS로 찾는다. (증가경로 찾긴)2. 증가 경로에 흐를 수 있는 최대 유량을 찾는다3. 찾은 증가 경로에서 보낼 수 있는 최대 유량을 흘린다.2. 에드몬드 카프 알고리즘: BFS📕 컴퓨터 구조✅ 제어장치📌 명령어제어장치: RAM에 저장된 데이터를 가져와 정해진 동작을 수행하는 장치이다.명령어, 데이터 모두 제어장치에 저장되어 있음.상위 4비트 명령어, 하위 4비트 데이터(주소, 값)📌 프로그램 카운터RAM에서 메모리 주소를 이동시키거나 원하는 주소로 바로 접근할 수 있게 해주는 장치다음 실행한 명령어의 주소를 가리킨다.JK Flip-Flop을 통해 메모리 주소 1씩 카운팅혹은 JUMP를 통해 원하는 주소로 바로 이동 📌 스탭 카운터명령어 인출, 해석 및 실행 단계를 카운팅해주는 장치후기이번 주차에서는 그래프와 다양한 알고리즘에 대해서 배웠다. 매일 알고리즘 문제를 풀면서 개념은 알지 못하였지만 dfs나 bfs 혹은 그래프 문제를 해결하면서 접한 풀이과정에 대해 익혀가면서 단순히 재귀적인 문제의 심화 과정이라고 생각을 하였지만 이번 과정에서 해당 개념에 대해 깊이 있게 배울 수 있었고 간단한 풀이 예시와 함께 공부하다보니 더 쉽게 체감해볼 수 있었다. 컴퓨터 구조에서는 지금까지 배웠던 개념들을 토대로 본격적인 CPU 를 간단하게 제작해볼 수 있는 실습이 진행되었다. 개념적인 내용은 실습을 진행하면서 깊이 있게 다루지는 못하였지만 실제 동작되는 과정을 보면서 CPU의 명령과 연산 하나하나가 어떻게 동작하는 지 확인해볼 수 있었다. 점점 다양한 입력 핀들과 동작들을 혼합하여 제작하니 점점 구조가 복잡해지고 이해하는 것이 어려워지긴 하였지만 복습과 미션을 통해서 더 깊이 있게 이해해보려고 한다.

알고리즘 · 자료구조자료구조알고리즘컴퓨터구조

박승민

[워밍업 클럽 4기 BE] 3주차 발자국

강의강의명: [Practical Testing: 실용적인 테스트 가이드]학습 내용: 섹션6.이번 주는 Spring을 통해 Layered Acrchitecture에서 단위 테스트와 통합 테스트를 어떻게 수행하는지를 확인할 수 있었다.테스트를 작성하는 노하우 이외에도 트랜잭션 설정, CQRS 등 추가적으로 고민해볼 키워드도 많이 배웠다.Persistence LayerData JPA 프레임워크 기반에서 테스트를 진행했다.실제 DB 대신 local in-memory 환경을 활용해서 도메인 객체의 생명주기를 어떻게 다룰지 확인해봤다.Business Layer핵심 비즈니스 로직이 위치한 계층은 단위 테스트보다는 통합 테스트를 어떻게 진행하느냐가 중심이었다.여러 레이어와 의존 관계를 맺고 있는 구조라서, 트랜잭션 전파나 데이터 정합성 같은 문제를 Persistence Layer와 함께 통합 테스트를 할 때 이런 부분들을 신경쓸 수 있었다.미션읽기 좋은 코드 강의를 수강하면서 실습을 따라하거나 이전 미션을 진행할 때마다, 변경사항이 생기면 수동으로 테스트를 해야 해서 불편함이 있었다. 이번 미션을 통해 그 불편함을 해소할 수 있었다.단순히 강의를 듣고 예제를 따라하는 데서 그치는 게 아니라, 직접 내 생각을 코드로 옮겨보고, 그 과정에서 생긴 여러 의문들을 고민하고 해결하면서 즐겁게 미션을 수행할 수 있었다.회고요구사항이 추가되면서 코드에 변경이 생겼고, 그럴 때마다 테스트 코드가 얼마나 든든한지 느꼈다.리팩토링할 때 불안하지 않았고, 테스트가 잘 돌아가는 걸 보면서 안심할 수 있었다.읽기 좋은 코드와 단위 테스트를 지나 단순한 자바 프로젝트가 아니라, 실제 서비스와 비슷한 구조에서 테스트가 어떤 의미를 가지는지 배울 수 있었다.테스트 코드는 단지 정상 작동을 확인하는 게 아니라, 프로덕션 코드가 의도한 대로 동작하는지, 예외 상황에서도 잘 처리하는지를 확인하는 수단이었다.테스트를 “하는 것” 자체보다, 테스트라는 도구가 개발 전체에 어떤 영향을 주는지 생각하게 됐다.이번 미션에서 예제가 두 개 중 하나를 택하여 그중 하나만 테스트를 진행하였는데 미션을 수행하다보니 "조금 더 여유 있게 시작했으면 나머지 예제도 테스트 코드를 작성해봤으면 좋았을텐데" 하는 아쉬움이 남는다.

suover

인프런 워밍업 클럽 스터디 4기 - CS 전공지식 3주차 발자국

그림으로 쉽게 배우는 자료구조와 알고리즘 (심화편)만들면서 쉽게 배우는 컴퓨터 구조강의와 함께한 인프런 워밍업 클럽 스터디 4기 - CS 전공지식 (자료구조, 알고리즘, 컴퓨터구조)3주차 발자국 입니다.학습 내용 요약자료구조·알고리즘트라이(Trie)와 자동완성개념: 문자열 집합을 효율적으로 저장·탐색하기 위해, 각 노드가 문자 하나를 나타내며 공통 접두사를 공유하는 트리 구조입니다.학습: 삽입 및 탐색 로직의 흐름을 개념적으로 이해하였습니다.인사이트: 삽입·탐색이 문자열 길이에 비례하기 때문에, 대규모 단어 집합에서 접두사 검색이 빠르지만 메모리 사용이 커질 수 있음을 감안해야 함을 체감했습니다.그래프개념: 그래프는 정점과 간선으로 관계를 표현하는 자료구조로, 방향 여부나 가중치 유무에 따라 다르게 다루며 인접 리스트와 인접 행렬 방식으로 표현할 수 있습니다.학습: 간단한 예제 그래프를 구성해 보고, DFS는 재귀나 스택으로 깊이 우선 탐색하며 방문 체크로 순환을 막고, BFS는 큐로 레벨별 탐색해 비가중치 최단 경로에 유리함을 코드로 확인했습니다.인사이트: DFS는 깊이 탐색이 필요할 때, BFS는 단계별 탐색이 필요할 때 유용하며, 그래프 표현 방식도 데이터 크기와 목적에 맞춰 결정해야 한다는 점을 깨달았습니다.가중 그래프와 다익스트라 알고리즘개념: 가중치가 있는 그래프에서 시작 정점으로부터 다른 정점까지 최단 경로를 찾는 문제입니다.다익스트라 알고리즘원리: 현재까지 알려진 최단 거리 후보 정점을 선택해 인접 간선을 완화(relaxation)하며 거리 배열을 갱신합니다.인사이트: 그래프가 커질수록 일반 방식은 느려지고, 우선순위 큐(힙)를 쓰면 더 빠르게 최단 경로를 구할 수 있음을 느꼈습니다.컴퓨터 구조제어 장치 없는 컴퓨터 & 조립CPU 주요 구성 요소(CPU 레지스터, ALU, 프로그램 카운터, 스텝 카운터)를 복습하고, 실습을 통해 신호 흐름을 이해했습니다.CPU 만들기: 제어 장치(Control Unit)명령어 처리 흐름: 명령어 인출(fetch), 디코딩, 실행(execute) 단계의 제어 신호 타이밍을 확인했습니다.주요 명령어: NOP, LOADA, ADD, SUB, STOREA, LOADI, JMP/JMPC/JMPZ, OUT, HLT 등의 제어 신호와 ALU·레지스터·메모리 동작 방식을 이해했습니다. 제어 장치 조립: Logisim에서 각 단계별 신호를 조합해 제어 유닛을 완성하고, 시뮬레이션으로 신호 흐름과 분기 동작을 확인했습니다.미션🎯 자료구조·알고리즘 미션3: 허프만 코딩 구현목표주어진 문자열에 대해 HuffmanCoding.compress(str)를 호출했을 때, [ [문자, 코드], … ]형태의 배열을 출력하도록 허프만 코딩을 구현합니다.class Node { constructor(char = null, freq = 0, left = null, right = null) { this.char = char; this.freq = freq; this.left = left; this.right = right; } } class HuffmanCoding { compress(str) { if (!str) return []; // 빈도 계산 const freqMap = new Map(); for (const ch of str) { freqMap.set(ch, (freqMap.get(ch) || 0) + 1); } // 초기 노드 리스트 생성 const nodes = []; for (const [ch, f] of freqMap.entries()) { nodes.push(new Node(ch, f)); } // 허프만 트리 구성 while (nodes.length > 1) { nodes.sort((a, b) => a.freq - b.freq); const a = nodes.shift(); const b = nodes.shift(); nodes.push(new Node(null, a.freq + b.freq, a, b)); } const root = nodes[0]; // 코드 생성 const codes = {}; const build = (node, prefix) => { if (node.char !== null) { codes[node.char] = prefix || "0"; } else { build(node.left, prefix + "0"); build(node.right, prefix + "1"); } }; build(root, ""); // [문자, 코드] 쌍 배열 반환 return Object.entries(codes); } } const huffmanCoding = new HuffmanCoding(); const str = "Lorem ipsum dolor sit amet consectetur adipiscing elit. " + "Consectetur adipiscing elit quisque faucibus ex sapien vitae. " + "Ex sapien vitae pellentesque sem placerat in id. " + "Placerat in id cursus mi pretium tellus duis. " + "Pretium tellus duis convallis tempus leo eu aenean."; const result = huffmanCoding.compress(str); console.log(result);흐름 및 구현 요약빈도 계산문자열을 순회해 Map 또는 객체에 문자별 등장 빈도를 집계했습니다.코드 생성재귀 탐색으로 왼쪽 자식은 '0', 오른쪽 자식은 '1'을 prefix에 추가하며 리프에서 코드 할당. 단일 문자 입력 시 빈 prefix에 "0" 처리 로직도 반영했습니다.검증실행 결과에서 빈도가 높은 문자는 짧은 코드, 낮은 문자는 긴 코드가 할당되는지 확인했습니다.빈도와 코드 길이 관계가 적절한지, 모든 문자가 포함되었는지, 코드끼리 충돌이 없는지 점검했습니다. // 결과 [ [ 'i', '000' ], [ 'q', '001000' ], [ 'v', '001001' ], [ 'o', '00101' ], [ 'l', '0011' ], [ 'd', '01000' ], [ 'E', '0100100' ], [ 'g', '0100101' ], [ 'x', '0100110' ], [ 'P', '0100111' ], [ 'a', '0101' ], [ 'e', '011' ], [ 'm', '10000' ], [ 'r', '10001' ], [ 'u', '1001' ], [ 't', '1010' ], [ 'p', '10110' ], [ 'L', '10111000' ], [ 'C', '10111001' ], [ 'f', '10111010' ], [ 'b', '10111011' ], [ '.', '101111' ], [ ' ', '110' ], [ 's', '1110' ], [ 'c', '11110' ], [ 'n', '11111' ] ]느낀 점허프만 코딩의 "빈도 기반 병합 → 트리 구조 → 코드 생성" 흐름을 직접 구현하며 원리 습득이 명확해졌습니다. 결과 검증 과정에서 빈도와 코드 길이 관계, 프리픽스 성질 확인 등이 중요함을 체득했습니다. 🔗 자료구조·알고리즘 미션3 블로그 링크🎯 컴퓨터 구조 미션3: STOREB 명령어와 A·B 비교 어셈블리어 구현목표STOREB 명령어(OPcode 1001)를 추가해 레지스터 B의 값을 메모리 주소에 저장하도록 구현합니다.A와 B 값을 비교해 같으면 0, A>B면 1, A<B면 2를 출력 레지스터에 내보내는 어셈블리어를 작성하고 검증합니다.구현STOREB(1001) 명령어 추가기존 STOREA 처리 경로를 참고하여 opcode 1001 분기 로직을 제어 장치에 추가했습니다.스텝 카운터가 각 단계에 진입할 때, STOREB 신호와 연관된 핀들이 의도한 타이밍에 활성화되는지 확인했습니다.A·B 비교 어셈블리어메모리에 저장된 A와 B 값을 불러와 비교하는 순서LOADA addrA → SUB addrB (A = A - B, 플래그 설정)JMPC 분기로 A≥B 처리, 아닐 경우 LOADI 2로 A<B 결과 세팅 후 출력분기한 경우 ZF 검사: ZF=1일 때 A=B(LOADI 0), ZF=0일 때 A>B(LOADI 1)이후 OUT, HLT로 마무리주소 라벨 매핑과 분기 주소 계산을 꼼꼼히 검토했습니다.Logisim에서 다양한 A·B 조합 테스트를 통해 출력 레지스터가 기대값(0/1/2)을 잘 내보내는지 확인했습니다.LOADA 14 // A = RAM[14] SUB 15 // A -= RAM[15] JMPC 5 // CF = 1 → A ≥ B일 때 5번 주소로 점프 LOADI 2 // A < B → 결과 2 JMP 9 // 결과 출력으로 점프 JMPZ 8 // ZF = 1 → A = B일 때 8번 주소로 점프 LOADI 1 // A > B → 결과 1 JMP 9 // 결과 출력으로 점프 LOADI 0 // A = B → 결과 0 OUT // 결과 출력 HLT // 프로그램 종료 0 0 0 7 // A값 3 // B값느낀 점제어 장치에 새로운 명령어를 추가할 때, 기존 신호 경로와 타이밍 흐름을 정확히 이해해야 오류를 줄일 수 있음을 확인했습니다.분기 주소 계산이 미흡하면 예상치 못한 동작이 발생하므로, 어셈블리어 작성 시 라벨 관리가 중요함을 체감했습니다. 🔗 컴퓨터 구조 미션3 블로그 링크회고잘한 점단계적 접근: 컴퓨터 구조와 알고리즘 미션을 작은 단위로 나눠 핵심 로직과 흐름을 차근차근 구현하고 검증했습니다.디버깅 습관 강화: Logisim 시뮬레이션과 코드 실행 결과를 반복 확인하며, 문제 발생 시 신호 흐름이나 분기 주소 동작을 빠르게 점검했습니다.이론·실습 병행: 트라이, 그래프, 다익스트라 개념 학습 뒤 직접 구현 연습, 제어 유닛 명령어 설계 뒤 Logisim 실습, 허프만 코딩 이론 뒤 코드 작성으로 이론과 실습을 잘 연결했습니다. 아쉬웠던 점 & 보완테스트 부족 : 테스트가 부족해 다양한 상황을 확인하지 못했습니다. 다음에는 다양한 입력과 경계값을 더 많이 시도해 보겠습니다.성능 최적화 부족: 성능 최적화 연습이 부족했습니다. 시간이 된다면 구현했던 자료구조와 알고리즘을 재작성해보고, 다양한 시도를 통해 실행 시간을 비교해 보겠습니다. 마치며이번 주차에는 Trie, 그래프, 다익스트라 학습을 진행하고, 제어 장치 명령어 확장과 허프만 코딩 구현 미션을 병행하며 이론과 실습을 모두 경험했습니다. 단계별 실습을 통해 개념이 실제 코드나 회로로 연결되는 과정을 체감했고, 디버깅과 테스트 습관을 강화할 수 있었습니다. 다음주에는 추가 알고리즘 학습을 통해 더욱 탄탄한 이해를 쌓아가겠습니다. 감사합니다!

알고리즘 · 자료구조인프런워밍업클럽스터디CS전공지식자료구조컴퓨터구조발자국회고4기

rhkdtjd_12

[인프런 워밍업 클럽 4기 - DevOps] [미션5]컨테이너 이미지 사례 실습

컨테이너 이미지 사례 실습 ▶ 사전 준비사항# 도커 파일 및 App 소스 다운로드 curl -O https://raw.githubusercontent.com/k8s-1pro/install/main/ground/etc/docker/Dockerfile curl -O https://raw.githubusercontent.com/k8s-1pro/install/main/ground/etc/docker/hello.js [root@cicd-server ~]# ls Dockerfile hello.js<전체 실습 명령어>1. docker build -t 1pro/hello:1.0.0 . 2. docker image list 3. docker tag 1pro/hello:1.0.0 1pro/hello:2.0.0 4-1. docker login -u 1pro 4-2. docker push 1pro/hello:1.0.0 5. docker rmi 1pro/hello:1.0.0 6. docker pull 1pro/hello:1.0.0 7. docker save -o file.tar 1pro/hello:1.0.0 8. docker load -i file.tar 1. 빌드2. 이미지 리스트 조회3. 태그 변경4-1. 로그인4-2. 이미지 업로드5. 이미지 삭제6. 이미지 다운로드7. 이미지 -> 파일로 변환▶ 이미지 삭제8. 파일 -> 이미지로 변환▶ 정리컨테이너디 (Containerd)<전체 실습 명령어>1. ctr ns list 2. ctr -n k8s.io image list 3. ctr images pull docker.io/1pro/hello:1.0.0 4. ctr images tag docker.io/1pro/hello:1.0.0 docker.io/1pro/hello:2.0.0 5. ctr image push docker.io/1pro/hello:2.0.0 --user 1pro 6. ctr -n default image export file.tar docker.io/1pro/hello:1.0.0 7. ctr -n k8s.io image import file.tar 8. ctr -n k8s.io image remove docker.io/1pro/hello:1.0.0 1. 네임스페이스 조회2. 특정 네임스페이스 내 이미지 조회3. 다운로드 및 이미지 확인 (이미지는 default라는 네임스페이스에 다운 받아집니다.)4. 태그 변경5. 업로드6. 이미지 (namespace : default) -> 파일로 변환7. 파일 -> 이미지로 변환 (namespace : k8s.io)8. 삭제 (namespace : k8s.io)같은 이미지를 도커에서 받았을 때와 쿠버네티스에서 받았을 때 사이즈가 다른 이유▶ Docker Hub (248.26 MB)▶ Docker (520MB)▶ Containerd (247.8 MiB)1. Container Image를 만들 때 플랫폼(amd64, arm64)을 고려해야 되는데, Docker에서는 amd64를 받았고, Kuberentes에서 arm64를 받아서 이미지 크기가 달라졌을 것이다.▶ Docker Hub에 올라간 이미지는 amd64 [win, linux]과 arm64 [mac m series]을 지원▶ Docker (amd64가 보임)▶ Containerd (amd64, arm64)가 보임분석 :해당 Image는 Mac M 시리즈나 Window 유저가 모두 다운받을 수 있도록 만들었습니다. 그래서 한 Image에 amd64, arm64 버전이 각각 있는 거고요.현재 저는 Linux (adm64)에서 이미지를 다운로드를 실행 했고, Docker에서는 amd64 이미지를 받았고, Containerd에서는 amd64와 arm64 둘다 있는 걸로 보아 두 버전이 모두 사용가능한 이미지가 다운 받아진 것 처럼 느껴질 수 있습니다.그럼 두 버전을 모두 받은 Containerd 이미지가 더 커야 할 텐데, 오히려 이미지가 더 작아요.​결론 :Containerd에서 PLATFORMS는 그냥 해당 이미지가 어떤 플랫폼을 지원하는지 정보를 보여준 것이지, 실제 여러 플랫폼에서 실행 가능한 이미지를 받았다는 의미는 아닙니다.내가 amd64 환경에서 다운로드 했다면, Containerd는 알아서 amd64의 이미지를 다운 받아와요.그렇기 때문에 Docker나 Containerd 에서는 같은 amd64 이미지를 다운받았고, 결국 Size도 같아야 합니다.​2. Container 이미지는 각각의 Layer로 구성돼 있는데, Docker에서 다운 받을 때는 전체 Layer를 받았고, Kubernetes에는 기존 이미지에 이미 존재하는 Layer가 있기 때문에 새로 받은 이미지의 Size가 작게 조회 됐을 것이다. ▶ Docker -> Containerd1. 파일로 변환2. 복사3. 이미지로 변환▶ Containerd -> Docker1. 파일로 변환2. 복사3. 이미지로 변환분석 :Docker의 이미지를 파일로 변경 했을 때는 이미지 사이즈가 약간 작아졌지만, 큰 차이가 없었고, 그 파일을 Containerd로 Import 했을 때 사이즈의 변화는 없었습니다.반면 Containerd의 이미지를 Docker로 넣었더니 이미지가 증가했네요.Docker로 다운 받나, Containerd로 다운 받나 어차피 같은 동작을 하는 이미지이고, 각각 최초 조회 되는 Size가 달랐어도, 이동되는 파일이나, Import 시에 파일 사이즈가 좀 이상해 보입니다.결론 :Container의 이미지는 Layer 방식으로 만들어지며, A 이미지가 1, 2, 3 레이어를 가지고 있고, 각 레이어의 크기가 1MB라고 했을 때, 1, 2, 3, 4 레이어를 가지진 B 이미지를 다운받는 다면, 4 레이어만 다운 받으면 되고B 이미지는 기존 A 이미지가 가지고 있는 1, 2, 3 레이어를 같이 사용하고, 거기에 4 레이어만 해서 자신의 이미지를 만듭니다.​그래서 A와 B의 이미지를 조회 할 때는, A-3MB, B-4MB로 보이지만, 내부적으로는 4MB만 사용을 해요. 컨테이너 이미지는 조회 권한만 있는 스냅샷이기 때문에 다른 이미지에서도 같이 레이어를 공유해서 사용할 수 있고, 거기에 내 레이어를 추가하는 방식으로 구성 됩니다. 그래서 필요한 레이어만 다운 받으면 되니 컨테이너가 Disk 자원적으로는 매우 유리한 거죠.​이런 관점에서 볼때, 위 그림에서 최초 조회된 사이즈 (Docker-490MB, Containerd-248.3MiB)는 내부적으로는 어떻게 사용되고 있는지 모르겠지만, 해당 이미지를 구성하는 전체 사이즈가 맞습니다.​그래서 결국 Docker에서 Containerd로 이미지를 가져갔을 때 Size가 그대로이고, 반대로 Containerd에서 Docker로 이미지를 가져갔을 때는 Size가 증가하는 원인을 찾아야 합니다. 3. 쿠버네티스에는 다른 Runtime을 사용했을 수 있고, 같은 이미지더라도 사용하는 Runtime에 따라서 이미지의 크기는 달라질 것이다.분석쿠버네티스는 Runtime으로 Docker나 Containerd 둘중 하나를 선택할 수가 있는데, 예전에는 주로 도커를 사용했지만 현재는 Contaienrd가 기본으로 사용되고 있다.이미지 사이즈가 다른 이유는 Docker와 Kubernetes가 아닌 Docker와 Contaienrd의 차이이다.결론Docker는 다른 많은 기능들을 지원해 주기 때문에 실제 이미지가 247.8 MiB라고 하더라도 다운 받은 이후 자신의 메타데이터 규격에 맞게 데이터들을 더 추가하고 이미지를 재구성한다. 그래서 520MB가 된 것이다. Containerd에서 이미지를 가져왔을 때도 마찬가지로, 이미지를 재구성 하느라 Size가 커졌다.반대로 Docker의 이미지를 Contaienrd로 가져가게 됐을 때, Docker에서 재구성을 하느라 커진 불필요한 메타데이터들이 그대로 들어간 것이다.꼭 알고 넘어가야 하는점인터넷이 연결되지 않는 환경에서는 이미지들을 다운 받아서 파일 형태로 복사를 해야된다.이때 쿠버네티스에서 Contaienrd를 사용한다면 Docker로 받은 이미지를 복사해 넣을 경우 불필요하게 이미지 사이즈가 커지게 됩니다. 

데브옵스 · 인프라쿠버네티스

일프로 3주차 발자취

* 손쉽게 데브옵스 환경을 구축하는 방법- Vagrant랑 스크립트로 Jenkins, K8s, Docker 환경을 한 번에 구성함- Jenkins 대시보드랑 K8s 대시보드까지 바로 접속 가능하게 되어 있음- kubectl 인증서 복사해서 사용하는 구조 실습- VM 네트워크 구성이랑 Jenkins가 이미 설치된 상태라 실습 위주로 진행 가능함- 기본적으로 DevOps 환경에 필요한 구성요소를 다 갖춘 느낌→ 직접 설치 안 해도 되는 게 편했고, 환경 구조 자체를 이해하기엔 괜찮았음* 배포를 시작하기 전에 반드시 알아야 할 것들- CI/CD 전반 흐름 설명 (개발 → 테스트 → 빌드 → 배포 → 운영)- 배포 전략 종류 비교: Rolling Update / Blue-Green / Canary→ 단순히 yaml만 만지는 게 아니라, 전체 흐름이 머릿속에 좀 정리되는 느낌* Jenkins Pipeline 기초부터 Blue-Green까지- Jenkinsfile로 파이프라인 구성: 소스 빌드 → 컨테이너 빌드 → 쿠버네티스 배포- Blue/Green 배포 실습: 두 버전 배포하고 selector 바꿔서 트래픽 전환- 수동 전환도 해보고, 자동화 스크립트도 따로 구성해봄- 버전 관리, 라벨/셀렉터 활용하는 구조 이해하는 데 도움이 됨→ 직접 파이프라인 돌아가게 해보니까 전체 흐름이 눈에 보임. 생각보다 할만했음* Helm과 Kustomize 비교하며 사용하기- Helm: 패키지처럼 앱 배포, 템플릿 구조. values.yaml로 설정 주입- Kustomize: base + overlay 방식. 간단한 환경 오버레이 구성에 유리- Helm은 재사용성 좋고, Kustomize는 직관적인 구성에 강점→ 헬름 구조 익숙해지면 생각보다 어렵진 않음. 실무에선 둘 다 써야 할 듯 

ddd

[워밍업 클럽 4기: DevOps] 3주차 회고

[3주차에 접어들면서]일을 병행하면서 공부를 하다보니 시간이 잘 안가서 복습까지 이어가긴 힘들었고 강의를 들으면서 이해하는 학습을 위주로 공부했습니다.주말에도 일정이 있어서 다음주에 시간을 쪼개서 못했던 복습들을 작성할 계획입니다 [DevOps]데브옵스 한 방 정리 강의를 통해 DevOps가 단순한 도구 사용이 아닌, 조직 문화와 프로세스 개선의 관점에서 접근해야 한다는 것을 깨달았습니다. 그리고 손쉽게 데브옵스 환경을 구축하는 방법에서 직접 간단한 데브옵스 파이프라인(Git + Jenkins + Docker + Kubernetes 파이프라인)을 구현하는 법을 배웠는데 실무에서 사용할때 기반으로 사용하면 좋겠다는 생각을 했습니다. [CI/CD, Helm/Kustomize]Jenkins Pipeline 강의에서는 역시 Jenkins Blue/Green 배포가 특히 인상적이었습니다. 이론으로만 알고 있던 무중단 배포를 실제로 구현해보니, 서비스 안정성이 얼마나 중요한지 체감할 수 있었습니다.Helm과 Kustomize 비교 강의에서는 각 도구의 철학적 차이를 명확히 이해할 수 있었습니다. Helm의 템플릿 기반 접근법(복잡한 애플리케이션 패키징, MSA 환경..)과 Kustomize의 오버레이 방식(단일 애플리케이션 또는 간단한 구조, GitOps 환경)이 어떤 상황에서 더 적합한지 판단할 수 있게 되었습니다.   

ddd 17일 전

쿠버네티스 어나더 클래스(지상편)-인프런 일프로강사님 / 3주차 발자국

강의 수강일주일 간 학습한 내용데브옵스 한방 정리개발 경험이 없다보니 개발부터 코드 관리, 테스트, 배포 그리고 운영 과정에 대한 개념이 없었지만 그래도 강의를 통해 조금은 이해가 됐습니다.그리고 여러 툴 들이 있어서 정신없기는 하지만 확실히 강사님이 말씀하신 것 처럼 한 두개의 툴들을 하나씩 경험하고 미숙하게나마 다루고 방법을 알게 되면서 해당 오픈 소스들이 더 잘 와닿고 접하는데 있어서 두려움? 이 사라지는 것 같습니다.MLOps나 FinOps는 들어봤는데 간략하게나마 설명해주셔서 해당 용어가 무슨 뜻인지 알게 됐습니다. 손쉽게 데브옵스 환경을 구축하는 방법깃허브와 도커허브는 이미 가입해 놓은 계정이 있어서 해당 계정을 사용했습니다.CI/CD 환경에서 쓸 오픈 소스로 Gradle, Jenkins, OpenJDK 프로그램을 새로 접하고 설치(강사님이 배포한 파일을 이용) 및 설정 하는 방법을 배웠습니다. 배포를 시작하기 전에 반드시 알아야 할 것들CI/CD 파이프라인 구성부터 배포 전략 선택 시에 신경써야할 요소들을 배웠습니다.이후 단계별로 차근차근 단순한 배포 파이프라인부터 점진적으로 고도화 되는 배포 파이프라인의 단계를 배웠습니다.이 강의를 통해 앞으로 있을 내용을 미리 예측해보는 시간이었습니다.Jenkins PipelineJenkins Pipeline 기능을 이용해 CI/CD 환경을 여러 단계에 걸쳐 구축하는 방법을 배웠고 실습 과정까지 진행했습니다.1단계에서는 가장 기초적인 구성부터 이후 여러 과정으로 나눠 환경 구축하는 단계를 세분화 과정, 그리고 Blue/Green 배포를 만들어보고 자동화 과정까지의 단계를 직접 경험해봤습니다.실무에서는 해당 내용처럼은 하지 않는다고 말씀해주셨지만 확실히 직접 실습해보니 개념이 더 잘 이해됐습니다. Helm과 Kustomize 비교하며 사용하기 - Helm 배포쿠버네티스 패키지 매니저인 Helm과 Kustomize의 공통점 및 차이점에 대해 간략하게 배웠습니다. 그 중 이번 주차는 Helm에 대해서 배웠는데 각각의 기능과 목적에 따라 나눠 놓은 것이 ansible의 role과 비슷하다는 느낌을 받았습니다.Helm 파일들을 나열하고 수정하는 부분에서 놓친 것 같아서 해당 파트의 수업을 여러 번 다시 볼 예정입니다. 회고아쉬운 점Helm 부분 따라가다가 놓친 것 같습니다.복습을 아예 놓쳤습니다... 급하게 미션 2,3,4 하다 보니 100프로 이해하지 못 한채 결과까지만 내본 것 같습니다. 보완하고 싶은 점미리 미션을 진행하면서 이해를 100퍼센트 하고 싶습니다. 나아진 점강의를 이해하는 정도가 점점 나아지고 있는 것을 느낍니다.강의를 보면서 실습을 따라하는 것이 더욱 익숙해 졌습니다. 미션2, 3, 4솔직히 처음 미션 내용을 받고 나서 어떻게 진행해야 할지 감이 안 왔는데 생각해보고 조원들에게 도움도 받으면서 미션을 진행했습니다.100프로 이해하지 못하고 결과만 받기 위해 따라 한 미션도 있지만 그래도 강의 내용을 한 번 더 복기하면서 진행하니까 해당 기능들을 왜 사용하는 지는 감을 잡았습니다.  

놀해

워밍업 클럽 4기 PM/PO 3주차 발자국

  내용 정리4-1 데이터 분야, 통틀어 하는 일은?데이터를 통해 현황 파악 PM 역할더 자세히 들여다 보고 패턴 찾기 PM 역할패턴을 토대로 미래 예측 → 데이터 사이언티스트 역할한정된 시간, PM이 가장 먼저 배워야 할 데이터 역량은?[의사결정 전=문제 파악 전] 지표를 이용해 우리 사업 현황 한눈에 파악[의사결정 전=문제 파악 전] 데이터를 깊이 들여다 보고 인사이트/패턴 찾기[실행 전] 미리 타당성 평가(;성공할지 예측은 못해도), 우선순위 세우기[실행 후] 결과(지표) 정량적으로 측정 및 평가상관관계 찾기[의사결정 전=문제 파악 전]지표 활용 → 현황 파악지표: 섹션5 강의에서 세부적으로 다룸Acquisition: 고객을 얼마나 잘 획득하고 있나Engagement: 획득한 고객들이 제품을 잘 이용하고 있나Retention: 이들이 계속 고객으로 남아있는가, 이탈하는가Monetization: 이들을 통해 수익을 잘 만들어내고 있는가지표 대시보드스프레드시트 등으로 직접 만들거나프로덕트 애널리틱스 툴(PA tool) - Amplitude, Mixpanel 댓글 확인!그 툴도 안 쓴다면, SQL의 ‘추출’ 파트만 숙지하여 쿼리날리기 Business Intelligence (BI) tool - redash, Metabase, holistics, taleau DB와 연결하여 쿼리로 데이터 추출 → 시각화/대시보드엑셀 스프레드시트 역량 또한 필요[의사결정 전=문제 파악 전]데이터 땅파서 인사이트/패턴 찾기데이터 드릴 다운→ 데이터 해상도 증가 → 새로운 정보 & 인사이트?: 총집계된 지표를 자세히 쪼개서 보는 것예시) WAU(Weekly Active User)을 연령대별/지역별/신규&기존 나눠서HOW?데이터 다루는 능력: SQL쿼리, 엑셀 피벗 테이블, Product Analysis tool호기심과 집요하게 쪼개서 보기[실행 전]타당성 평가 = 할 만 한가?현재 많은 사용자들이 이용하고 있는가?지표에 개선의 여지가 많은가? [실행후]기능의 성과/결과 판단을 위한 지표 정량적 측정 및 평가Feature Adoption: 몇 명이 사용하는가?Feature Retention: 한 번 사용한 후에도 계속 이용하나?예시) 결제 전환율: 기능 추가 후 반응 확인5. 상관관계 찾기예시) ‘가입 후 1주일 동안 하는 행동’이라는 변수와 ‘리텐션율’이라는 변수 사이 Cor 찾기페이스북/ 10일 내 실제친구 7명과 연결되면 리텐션율 높아짐.필수는 아님 4-2 어떤 역량이 필요하고 쌓지?데이터 추척 관련 역량의도를 가지고 쌓을 데이터 정의 ⇒ Event Taxonomy(유저 행동 로그) 설계→ 이걸 하기 위해선, ‘활용하는’ 역량 필요데이터 활용 역량어떤 의사결정이 필요한지 정의그걸 위해 필요한 데이터 정의어떤 형태로 기록할지, 나중에 분석하는 상황 상상하기!그래서 어케 쌓지“실제로” “직접” 해보기 SQL, BI 툴, 프로덕트 애널리틱스 툴 등! 5-1 지표란? & Proxy 지표지표란?주기적으로 모니터링하는 지표매일/매주/매월 가입자, 활성 사용자, 매출, 리텐션율, 각종 전환율 등신규 유저 획득(Acquisition), Activation(활성화), Engagement, Retention(지속적 이용), Monetization(수익화)이런 지표들 중 모니터링할 지표 선정 및 tool 을 통한 대시보드화 or 스프레드 시트 활용일회성으로 확인하는 지표새로 만든 기능의 성과 지표 확인 - 의도한 바를 달성했는가Proxy, ‘가정’이 들어가는 지표뭔가(The Thing) 측정하고 싶은데, 직접 측정할 수 없다 → 대체물(Proxy)(예시) 명확&구체적: 지난 7일 간 회원 가입한 유저 ‘가정’이 필요: 지난 7일 간 신규로 활성화된 유저회사의 ‘핵심 가치’를 나타낼 수 있는 이벤트를 생각하기어차피 ‘가정’이 들어간 이상 완벽한 지표라고 할 수 없지만, 지표를 개선함으로써 ‘성과’가 날 것임.정확한 지표를 정의하는 것보다, 팀을 한 군데에 집중하도록 만드는 납득시킬 수 있는 ‘스토리텔링’과 ‘영향력과 리더십’이 중요함 5-2 Acquisition충분히 많은 신규 유저/고객를 획득하고 있는가?그들을 비용 효율적으로 획득하고 있는가?CAC (고객 획득 비용): 마케팅 비용 등 채널별로 봐야 함CLA (Customer Lifetime Value; 고객 생애 가치): 스타트업에서 의미 없음Payback Period (비용 회수 기간):고객 당 획득 비용을 언제 회수하나?스타트업에 실용적인 지표 5-3 ActivationActivation이란?신규 획득한 사용자들이프로덕트의 핵심 가치를 경험하는습관을 형성하는 것⇒ 초기 사용자 경험 매우 중요, 리텐션의 주요 인풋 중 Actiavtion이 가장 영향이 큼 (’모든 신규 사용자’가 대상이므로)Setup → Aha → Habit Moment모먼트는 감으로 정의하는 것이 아님. 장기 리텐션과 각 모먼트들의 상관관계 분석, 전환율 등 정량적 분석 반드시 필요기본적인 통계 지식 필요 → 그래야 분석 가능함Positive/Negative Predictive Value, Type-1/2 error, False negative 등Setup: 핵심 가치를 경험하기 위한 ‘준비’를 마친 순간Aha: 처음으로 ‘핵심 가치를 경험’하는 순간Habit: ‘습관’을 형성하는 순간⇒ 각 모먼트의 전환율 (ex. 신규 유저가 첫 3일 내 영상 컨텐츠 시청(aha) / 신규 유저가 첫 28일 내 화상 회의 4회 개최(habit))  회고완강 후 강의 내용을 기반으로 회사에 직접 적용할 로드맵을 짜봐야겠다. 지금 자세하게 필기하는 것보다는 이런 예시가 있구나 정도 알아두고, 나중에 직접 적용해볼 때 다시 강의자료를 확인하며 해보는 것이 좋겠다.회사의 핵심가치를 나타낼 이벤트는? 무엇일지 따로 생각하는 시간을 가졌다.아직 저연차라 그런가 경영스러운 감이 있음. 4-2에서 언급한 모든 지표가 실제 회사에서 적용가능할지 모르겠음. 4-3) 지금은 회사 상황을 반영한 각 모먼트가 대략적으로도 그려지지 않음. ‘준비’랑 ‘핵심 가치 경험’ 순간까지는 강제적으로 해주는 편인 것 같은데.. 습관 형성을 위해 우리가 매주 2~3번 알림을 보냄. 관련 현황은 어떨지? 미션 해결강의에서 소개한 지표를 제외해야 한다는 조건 때문에 마냥 쉽게 할 순 없었지만, 인터넷과 AI의 도움을 받아 완료할 수 있었다. 사실 회사엔 기본적인 데이터 분석 환경도 갖춰지지 않은터라 어떤 의사결정을 해야할지부터 할 게 많은데, 미션을 통해서 정리할 수 있는 기회였다.

기획 · PM· PO

[워밍업 클럽 4기 백엔드] 3주차 발자국

Practical Testing: 실용적인 테스트 가이드 강의를 수강하고 작성한 회고입니다. 1. 학습한 내용 및 회고통합 테스트 (Integration Test)여러 모듈이 협력하는 기능을 통합적으로 검증하는 테스트라이브러리와 프레임워크의 차이라이브러리는 외부에서 가져와서 내 코드에 쓰인다. 즉, 내 코드가 주체가 된다.프레임워크는 이미 갖춰진 환경이 주워지며, 내 코드가 수동적으로 프레임워크 안으로 들어가게 된다.Persistenc Layer 테스트에서는 데이터에 대한 CRUD 작업의 테스트를 진행하기 때문에 비즈니스 로직이 들어가서는 안 된다.Business Layer 테스트는 비즈니스 로직을 테스트하며, 트랜잭션을 보장해야 한다.@Transactional이 테스트 코드에만 있으면 문제가 될 수 있음을 뒤늦게 발견할 수 있기 때문에 주의해야 한다.Presentation Layer 테스트는 Controller 테스트로, 파라미터에 대한 최소한의 검증을 한다.그리고 Presentation Layer 테스트를 할 때, Business Layer와 Persistence Layer는 Mocking을 해서 테스트를 진행한다.@Transactional을 쓸 때 Command와 Query를 분리하자.Command상태를 변경하는 작업(CUD)을 한다.메서드 단위로 @Transactional(readOnley 기본값 false) 필요Query상태를 조회하는 작업(R)을 한다.@Transactional(readOnly = true) 필요 변경 작업(Command)은 데이터의 무결성을 위해 쓰기 트랜잭션이 필요하고, 조회 작업(Query)은 성능을 위해 읽기 전용 트랜잭션이 적합하기 때문인다. 회고부끄러운 이야기이지만 지금까지 @Transactional을 쓰면서 그냥 다 필요한 거 아닌가? 하면서 트랜잭션을 거는 조건을 생각하지 않은 채 사용했었다. 실제로는 트랜잭션의 성격과 사용 목적에 따라 명확하게 구분해야 하고, Command와 Query를 나누는 설계 자체가 데이터 무결성과 성능 모두에 영향을 미친다는 것을 알게 되었다.이제는 습관적으로 @Transactional을 붙이는 게 아니라, '어떤 목적으로 트랜잭션이 필요한가?'를 먼저 생각하고 적용할 수 있도록 노력해야겠다.그리고 'Spring과 Spring Boot 모두 프레임워크라고 불리는데 이 둘의 차이는 뭘까'라는 궁금증이 생겨 찾아봤다.Spring은 애플리케이션의 핵심 기능(예: 웹, 데이터 접근, 보안 등)을 개발할 수 있도록 다양한 모듈과 기능을 제공하는 프레임워크이고, Spring Boot는 이러한 Spring의 여러 기능을 더 쉽고 빠르게 설정하고 실행할 수 있도록 도와주는 프레임워크이다.그래서 이 둘의 역할은 다르지만, 개발자가 정해진 구조 안에 코드를 작성하고 실행하게 만든다는 점에서 둘 다 프레임워크라고 할 수 있다고 한다.  2. 단위 테스트 코드 작성 미션 회고 프로젝트는 스터디 카페 프로젝트로 선택했고, StudyCafePassType, StudyCafeSeatPass, StudyCafePassOrder의 단위 테스트를 작성했다.작은 단위부터 테스트를 하기 위해 StudyCafePassType, StudyCafeSeatPass, StudyCafePassOrder 순서대로 진행했다.StudyCafePassTypeTest에서는 도메인 규칙을 테스트하기 위해 StudyCafePassType.FIXED가 사물함 사용이 가능한 타입인지 테스트했고,StudyCafeSeatPassTest에서는 비즈니스 조건을 테스트하기 위해 고정석 이용권이 사물한 이용 가능 조건인지, 시간 단위 이용권은 사물함을 이용할 수 없는지, 사물함 이용권과 좌석 이용권의 타입과 기간이 같은지, 할인율에 따라 할인 금액이 올바르게 계산되는지 테스트했다.StudyCafePassOrder에서는 결제 금액 계산 로직이 정확하게 작동하는지 테스트했다.이번 미션을 통해서 단순히 코드가 잘 작동되는가를 확인하는 걸 넘어서, 도메인 규칙과 비즈니스 로직이 제대로 구현되었는지 테스트하는 수단이라는 걸 느낄 수 있었다.   출처Practical Testing: 실용적인 테스트 가이드

워밍업 클럽 4기 BE 클린코드&테스트 3주 차 발자국

금주에는 레이어드 아키텍처를 배우고 각 레이어 별로 테스트를 진행했습니다. Persistence Layer 는 Data Access의 역할을 맡아 CRUD가 실행되는 레이어입니다.Persistence Layer의 테스트를 위해 Spring Data JPA 를 구현한 Repository 및 서비스를 사용했고기본 엔티티를 설계 및 개발하며 ProductRepositoryTest 를 진행했습니다.Business Layer 는 비즈니스 로직을 담당하는 레이어로OrderServiceTest를 통해 Product를 저장하고 orderService를 통해 OrderDto인 OrderResponse를 만들며.extracting(), .containsExactlyInAnyOrder() 등 메서드를 사용해 검증을 진행했습니다.Presentation Layer는 외부 세계의 요청을 가장 먼저 받는 계층으로파라미터에 대한 최소한의 검증을 수행합니다.동시성 이슈가 발생할 수 있는 부분과 그에 대한 해결 방안을 간략하게 알아보았고성능 최적화와 조회용 메서드와 CUD 메서드를 분리하기 위해클래스 상단에 @Transactional(readOnly = true) 를 위치하고CUD 가 필요한 메서드 마다 @Transactional 애노테이션을 오버라이딩 시켜주었습니다. 레이어드 아키텍쳐 이외에 테스트를 위한 공통 설정에 대해서도 배웠습니다. application.yml 파일을 이용해 프로파일별(local, test)로 설정을 분리하는 방법을 배웠습니다.Test에 사용되는 애노테이션에는@SpringBootTest @DataJpaTest가 있습니다.@DataJpaTest는 리포지토리와 JPA의 설정을 가지고 CRUD 테스트를,@SpringBootTest는 서비스를 포함한 전체 테스트 진행 시 사용합니다.테스트 클래스에서 사용되는 @Transactional 자동 롤백 기능과 부작용에 대해서 공부하고@AfterEach 로 테스트 후 각 리포지토리를 롤백해주었습니다. 금주의 미션은 given, when, then 패턴, BDD 스타일을 이용하여테스트 시나리오를 작성하고, 레드/그린/리팩토링 순서로 테스트를 진행 및 구현하는 미션이였습니다.작성했던 메서드를 기반으로 테스트를 작성했기에 레드 그린 순서로 진행하지는 못 했지만어떤 시나리오를 작성하면 좋을지 생각해보고 작성에도 도움을 주었다고 생각합니다.다만 아쉬운 점은 미션을 수행하는 것에만 치중하여 스스로 테스트 리팩토링을 소홀하게 진행한 것이 아쉬웠습니다. 일과 학습을 병행하니 이 정도면 충분하지 않나 생각으로 보내 아쉬움이 많이 남는 한 주였던 것 같습니다.물론 많은 도움이 되는 강의와 미션이지만 스스로 더 많은 경험치를 쌓기 위해매일 진행하는 학습 이후 반드시 배운 내용을 정리하며 마무리하는 연습을 하려고 합니다.     

hyunolike

[인프런 워밍업 클럽 4기] DevOps 발자국 3주차

 [ 워밍업 클럽 3주차 회고 ]DevOps, 운영을 넘어 배포의 미학까지이번 주는 쿠버네티스와 DevOps의 경계를 넘나들며 실제 배포와 운영에 필요한 개념들을 본격적으로 다뤘다. ‘코드를 잘 짠다’에서 ‘서비스를 잘 운영한다’로 시야를 넓혀야 하는 시점이라는 걸 체감한 시간이었다. DevOps 한방 정리 – 다시 짚는 DevOps의 본질DevOps는 단순한 도구의 집합이 아니라, 개발과 운영을 잇는 철학이라는 점을 다시금 깨달았다. 강의 초반에 나왔던 “협업과 자동화, 그리고 빠른 피드백”이라는 키워드는 실무에서도 계속 떠오를 개념이었다.CI/CD 도구, IaC, 모니터링 등을 단순히 기술로만 접근하지 않고, 조직의 문제를 해결하는 도구로 바라보는 관점이 인상 깊었다. 손쉽게 DevOps 환경을 구축하는 방법 – 도구보다 구조로컬에서도 금방 구성할 수 있는 Git + Jenkins + Docker + Kubernetes 파이프라인을 따라 실습하면서, DevOps 환경 구축이 생각보다 가까운 일이라는 걸 느꼈다. 특히 Jenkins + Docker-in-Docker 환경에서의 트러블슈팅 과정은 값진 경험이었다.강사님의 조언처럼, 작게 시작해서 점차 확장하는 것이 DevOps 도입의 핵심이라는 것을 느꼈다. 배포를 시작하기 전에 반드시 알아야 할 것들배포는 코드가 완성된 이후의 마지막 단계가 아니라, 설계 초기부터 염두에 두어야 하는 과정임을 배웠다.버전 관리 전략rollback 대비config 분리보안 설정(Secret 관리)이러한 것들이 어떻게 배포 안정성과 연결되는지를 배운 파트였다. 실제로 ConfigMap과 Secret의 실무 사용법은 지금이라도 우리 프로젝트에 적용하고 싶을    Jenkins Pipeline - 기초부터 Blue/Green까지이번 주 가장 인상 깊었던 파트 중 하나. Jenkins의 Declarative Pipeline을 직접 구성하면서 CI/CD 파이프라인의 기본 흐름을 체득했다. checkout 부터 build, test, docker build, push, kubectl apply까지 이어지는 작업은 실제 서비스 배포와 크게 다르지 않았다.특히 Blue/Green 배포 전략을 Jenkins로 구현하는 실습은 흥미로웠다. 트래픽을 기존 서비스에서 신규로 안전하게 전환하는 과정을 직접 경험하면서, 무중단 배포의 핵심이 무엇인지 체감할 수 있었다. Helm과 Kustomize 비교하며 사용해보기Helm과 Kustomize는 쿠버네티스에서 반복적인 배포 작업을 어떻게 더 효율적으로 관리할 수 있는지를 보여주는 좋은 도구였다. Helm은 패키징과 버전 관리를 통해 ‘재사용 가능한 차트’를 만들 수 있고,Kustomize는 기존 YAML을 재구성해 환경별 관리에 용이했다.단순히 어떤 게 더 낫다가 아니라, “어떤 상황에서 어떤 도구를 선택할 것인가”가 중요한 포인트라는 강의의 메시지가 와닿았다. 실무 감각을 키워준 일주일이번 주는 실습이 단순한 따라 하기에서 벗어나, “왜 이렇게 하는가”를 고민하게 만드는 수준으로 심화되었다. 각 기술이 연결되어 배포-운영-모니터링의 흐름을 구성하는 구조가 점차 보이기 시작했다.또한, Jenkinsfile을 수정하고 helm/kustomize로 배포를 조절하는 흐름 속에서 DevOps 역할이 단순히 ‘자동화하는 사람’이 아닌, 시스템 안정성과 속도를 책임지는 사람이라는 점도 다시 생각하게 됐다. 다음 주를 준비하며이제는 쿠버네티스 위에서의 운영이 조금씩 익숙해지고 있다. 다음 주는 GitOps나 ArgoCD 등 더 높은 수준의 운영 자동화도 다룰 예정인데, 이번 주 내용을 기반으로 나만의 배포 전략을 설계해보는 것도 의미 있을 것 같다.“자동화는 결과이고, 그 이전엔 설계가 있다.”3주차를 지나며, 단순한 배포를 넘어 설계와 운영의 연결 고리를 깊이 고민하게 됐다. 

데브옵스 · 인프라

승현

[인프런 워밍업 클럽 4기] 3주차 발자국

이번주 학습 내용이번주는 Devops의 역할, 배포 방법, 쿠버네티스 패키지 매니저(Helm)에 대해서 학습했다.아무래도 개발자이다 보니, 위 그림을 인상 깊게 보았는데, 내가 경험해온 Devops 엔지니어 분들은 개발 영역은 하지 않으셨고, 개발 부분은 개발자가 맡아서 하는 R&R이 확실하게 분리된 환경에서 업무를 해왔는데, 결국 나의 능력을 높이기 위해서는 개발 + 인프라까지 다룰 수 있어야 하는 건 맞는 것 같다. ( AI가 무섭게 성장하고 있는 흐름에서는 더더욱...! )그리고 추후 PM/PL/아키텍트 역할을 맡게 되었을때도 전체적인 그림을 볼 수 있어야 하기 때문에 전문가처럼 깊게는 아니더라도 전체적인 흐름은 알고 있어야 할 것 같다. 사실 이미지를 보자마자 놀랬다🤣🤣이 많은 내용을 다 알고 있어야 한다고?! 생각했는데 강사님께서 스탭별로 진행하면 된다고 말씀주셔서 다행이었다...나는 인프라는 곧 비용이다. 라고 생각하는데, 인프라 환경에 필요한 장비 또는 클라우드 비용이 매섭기 때문이다.회사의 지갑 사정에 따라서 또는 회사의 투자 상황에 따라서 인프라 환경도 달라질 것인데, 각 재정 상황에 맞는 파이프라인을 구축하면 되는 것 같다. 배포 방식에서는 Recreate / RollingUpdate / Blue&Green / Canary 이렇게 4개의 종류를 배웠는데, 가장 좋은 건 역시 Canary인 것 같다. (서비스는 죽으면 안되니까!)다만 이것도 결국 쿠버네티스를 얼마나 다룰 수 있는지 역량에 따라서 달라질 것 같다. Canary 배포 중 가중치가 안바뀐다거나? / 배포가 실행이 안된다거나?-> 여러 상황에 대해서 수동으로 처리할 수 있게 대응이 필요할 것 같다.)또한 서비스의 특징에 따라서도 어떠한 배포 방식을 선택할지 달라질 것 같다. 무중단이 아닌 운영시간이 정해진 서비스라면?-> 꼭 Canary 배포 방식을 선택하지 않아도 될 것 같다.회고요즘 퇴근 후 저녁에 3km 러닝을 하고 있는데, 러닝을 하면서 느끼는 것이 무엇이든지 단번에 되는 것이 아닌 절대적인 시간이 필요하고, 그 시간을 인내하고 꾸준히 달리는 것이 중요한 것 같다.학습도 마찬가지라는 생각이 든다. 어떠한 지식을 단번에 학습하려고 하지 말고, 천천히 꾸준히 학습하는 것이 중요한 것 같다.저번주 발자국에 일프로님께서 댓글을 달아주셔서 얼마나 놀랬는지 모르겠다ㅎㅎㅎ 이번 스터디는 완주를 목표로 학습하고, 추후에 꼭 복습해야겠다. 항상 디스코드 스레드 보면서 힘을 얻어갑니다! 마지막 4주차까지 파이팅!💪💪

데브옵스 · 인프라Devops일프로워밍업클럽인프런4기데브옵스쿠버네티스k8s

박서연

[워밍업 클럽 4기 - 백엔드] 3주차 발자국

[인프런 워밍업 클럽 스터디 4기 - 백엔드]강의 출처 :Readable Code: 읽기 좋은 코드를 작성하는 사고법Practical Testing: 실용적인 테스트 가이드3주차 발자국 강의 수강학습 내용 요약레이어드 아키텍쳐와 테스트 : 레이어 층 (Persistence, Business, Presentation), 관심사의 분리, 통합 테스트Spring / JPA 훑어보기 & 기본 엔티티 설계 : 라이브러리, 프레임워크, 스프링 개념(IoC, DI, AOP), ORM, JPA(어노테이션, 엔티티 설계, Spring Data JPA)Persistence Layer 테스트 : 데이터 접근 역할, JPA Repository 테스트를 하는 이유Business Layer 테스트 : 비즈니스 로직 구현 역할, Persistence와 상호작용(서비스 통합 테스트), 트랜잭션 보장 (예외->롤백), 동시성 고민Presentation Layer 테스트 : 외부의 요청, Mocking 처리하여 단위 테스트, MockMVC, readOnly = true 3주차 회고 이번 주는 요구사항에 맞춰 기능을 하나씩 만들어보고 각 레이어별로 직접 테스트를 작성하며 보낸 시간이었습니다. 스프링 구조(컨트롤러, 레파지토리, 서비스)를 따라가면서 직접 간단한 서비스를 구현하니 그동안 헷갈렸던 부분들도 복습되고, 조금 더 친숙하게 느껴졌습니다. 특히 테스트를 배우기 전에는 왜 굳이 이렇게 하는지 잘 몰랐는데, 직접 테스트를 작성해보면서 어느 부분을 어떻게 테스트해야 하는지 알게 된 점이 정말 좋았습니다. 어노테이션의 정확한 사용법과 이유도 이번 기회에 확실하게 배울 수 있어서 무척 재미있었습니다. 스스로 칭찬할 점은 이번 주에는 미루지 않고 진도표에 맞춰 강의 수강을 잘 마쳤다는 것입니다. 미션도 하루만에 완수할 수 있어서 뿌듯했습니다! 다만 아쉬운 점은 여전히 코드 리뷰 신청에 용기를 내지 못하고 결국 고민만 하다가 신청하지 못했다는 것입니다. 코드와 글쓰기에 자신이 없어서 좋은 기회를 놓친 것 같아 아쉽지만, 그래도 다음 주 라이브를 통해 다른 분들의 고민과 코드를 보며 배워가고 싶습니다. 다음 주가 벌써 마지막이라니 아쉽기도 하고 기대되기도 하는데, 진도표를 따라 강의 수강과 미션들을 밀리지 않고 해내는 것이 목표입니다! 미션미션 해결 과정 미션 4 (Day11) : 이번 미션에서는 코드의 동작 흐름을 따라가면서 직접 단위 테스트를 작성했습니다. 기존 코드의 주요 로직을 테스트하기 위해 실행 흐름을 하나씩 나누고, 주석으로 번호를 붙이며 필요한 메서드를 명확히 구분했습니다. 특히 사용자 입력을 처리하는 InputHandler의 경우, 기존 코드 구조를 크게 바꾸지 않으면서 충돌 문제를 해결하려고 고민하다가 Scanner를 static에서 인스턴스 필드로 변경하고, 반복되는 입력 시뮬레이션 메서드를 리팩토링하여 중복을 제거했습니다. 이용권 목록 처리나 락커 사용 여부 결정, 주문 금액 계산 및 할인 적용 같은 핵심 로직은 모든 경우의 수를 꼼꼼히 체크하고, 결과 값에도 계산 과정을 포함하며, 테스트에도 실제 값을 그대로 사용하며 최대한 현실에 가까운 방식으로 테스트를 작성했습니다. 또한 @DisplayName 작성과 BDD 스타일을 활용하면서 최대한 테스트의 목적과 결과가 잘 드러나는 이름을 짓기 위해 노력하여 테스트 코드의 가독성을 높일 수 있도록 작성했습니다. 회고미션을 진행하며 테스트 코드가 단순히 코드의 확인 도구가 아니라, 코드 구조를 깊게 이해하고 개선하는 데 중요한 역할을 한다는 것을 깨달았습니다. 처음에는 이미 구현된 기능을 뒤늦게 테스트로 작성하다 보니 어떤 부분을 테스트해야 할지 어려웠고, 테스트하기 힘든 구조도 있어서 고민이 많았습니다. 기능과 테스트를 함께 작성하는 방식이 중요한 이유를 이번 미션을 통해 몸소 느낄 수 있었습니다. 특히 동작 흐름을 따라가며 기능에 가장 핵심이 되는 메서드를 찾고, 어떻게 테스트할지 고민하는 과정 자체가 흥미롭고 재미있었습니다. DisplayName과 BDD 스타일을 통해 테스트 코드의 가독성과 명확성을 신경쓰며 개발할 수 있던 점도 좋았습니다. 이번 경험을 통해 테스트가 단순한 검증 수단을 넘어 좋은 설계를 위한 도구이구나 싶은 생각이 들었고, 앞으로 개발 할 때도 기능 구현과 테스트 작성을 병행하며 효율적으로 작업해야겠다는 다짐을 하게 되었습니다. 

백엔드워밍업클럽

채널톡 아이콘