MINIWIKI
CareerSideProjectBook&Study
  • ⚡README
  • 😃ME
    • Review
      • 2025 OKR & 회고 - 회사 없이도 먹고살 수 있는 상태가 된다
        • 2025년 19주차
        • 2025년 18주차
        • 2025년 17주차
        • 소설쓰기의 쓸모
        • 2025년 15주차
        • 2025년 14주차
        • 요즘 회사생활
        • 첫 페이지 작성!
        • 큰 코 다쳤다
        • 오랜만에 좋았던 하루
        • 악순환과 반복실패
        • 2025년 12주차
        • 2025년 11주차
        • 2025년 3월 6일
        • 2025년 3월 4일
        • 2025년 3월 1일
        • 2025년 2월 회고
        • 2025년 1-2월 책, 영화, 음악
        • 2025년 1-2월 회고 (PM)
        • 2025년 1-2월 회고 (콘제품)
          • (Merged) 2025 비즈니스
        • 2025년 1-2월 회고 (삶/사람)
        • 2025년 1-2월 회고 (기본)
        • (25.02) 고객 피드백 받기
        • 다시 전략 수정
        • 머리 속 복잡한 것들 끄적끄적
        • 변하지 않는 핵심 철학
        • 개별화 능력을 이용하는 방법
        • 파고들기
        • 예술가와 사업가
        • 강점
        • PM으로서의 전문성
        • 부동시
        • 이게 다 무슨 소용인가
        • 내가 가장 잘 전할 수 있는 메시지
        • 연말인사 타이밍
        • Attitude는 옷부터
        • 다시 시작
      • 2024 회고
        • 2024년 12월 4주차 (52/52)
        • 원한다고 생각했던 것들
        • 2024년 12월 3주차 (51/52)
        • 회사 vs. 퇴사
        • 2024년 12월 2주차 (50/52)
        • 2024년 11월 4주차 (47/52)
        • 2024년 11월 3주차 (46/52)
        • 2024년 11월 1주차 (44/52)
        • 혓바늘
        • 2024년 10월 3주차 (42/52)
        • 그냥, 요즘하고 있는 생각들
        • 2024년 10월 1주차 (40/52)
        • 2024년 9월 4주차 (39/52)
        • 2024년 9월 3주차 (38/52)
        • 2024년 9월 2주차 (37/52)
        • 2024년 9월 1주차 (36/52)
        • 2024년 8월 4주차 (35/52)
        • 잃어버린 보물창고
        • 분기별 프로젝트
        • 강점검사
        • 글쓰기
        • 이상적인 하루
        • 나와 아프리카
        • 한 때 나에게 힘이되었던 문장들
      • 2023 회고
        • 2023년 12월 5주차
        • 2023년 12월 4주차
        • 2023년 12월 3주차
        • 2023년 12월 2주차
        • 2023년 12월 3일
        • 2023년 12월 1주차
        • 2023년 11월 29일
        • 2023년 11월 28일
        • 2023년 11월 27일
        • 2023년 11월 18일
        • 2023년 11월 15일
        • 2023년 11월 12일
        • 2023년 11월 11일
        • 2023년 11월 1주차
        • 2023년 10월 3주차
        • 2023년 9월 4주차
        • 2023년 9월 3주차
        • 2023년 9월 2주차
        • 2023년 9월 1주차
        • 2023년 8월 4주차
        • 2023년 8월 2주차
        • 2023년 8월 1주차
        • 2023년 7월 4주차
        • 2023년 7월 3주차
        • 2023년 7월 2주차
        • 2023년 상반기 회고
        • 나태하고 욕심많은 인간은 어떻게 살아야 하나
        • 책 <어떻게 살아야 하는가>
        • 책 <당신은 결국 무엇이든 해내는 사람>
        • 복잡계를 살아가는 단순한 사람
        • 책 <모든것이 되는법>
        • 글로 신뢰를 얻었던 경험들
        • 기획은 나를 찾아가는 과정
        • 나는 왜 살아가는가
        • 장항준 감독으로부터 배우는 "삶을 대하는 자세"
        • 개발자가 말하는 감정에도 분석이 필요한 이유
      • 2022년 회고
        • problem map 작성하기
        • 삶에서 내가 해결하고 싶은 문제 (2)
        • 삶에서 내가 해결하고 싶은 문제 (1)
        • <삶의 문제> 지도 다시 꺼내보기
        • 지도 위의 29살
        • 매번 시간계획을 망치는 MBTI 'P형 인간'을 위한 5단계 인생관리법
        • 당신은 왜 프로그래밍을 공부하는가?
        • 아무 것도 아닌 내가 글을 쓰는 이유
        • 책 <여행의 이유>
        • 책 <붕대감기>
      • 2021년 회고
    • Career
      • [미리캔버스] AI 제품 PM
        • 선택과 집중
        • 어쩌면 내가 틀릴 수도 있다는 생각
        • 뾰족한 사람들과의 협업
        • AI기능 PPT로 온보딩
        • AI 제품에서 가장 중요한 것
      • [미리캔버스] 앱 PM
      • [미리캔버스] 소상공인 제품 PM
      • [미리캔버스] 2.0 PM
      • [홀로스탠딩] 백엔드 개발
      • [청년5.5] 안드로이드 개발
      • [가축대출사업] NGO Project PM
    • Insight
    • Interview
    • Public Writing
  • SIDE PROJECT
    • [Youtube] 메이킹필름
      • [Product] 청춘집 프로젝트
        • (v24.11) 청춘집 JTBD
          • (구) 청춘집 실행계획
          • (구) 플레이리스트 기획
            • 데이식스 전곡 타임라인
            • 챕터 구성
        • (v25.01) 청춘집 JTBD
          • 아이돌 굿즈 시장 조사 (공식)
          • 아이돌 굿즈 시장 조사 (비공식)
        • 제작 준비
          • 레퍼런스 - 오프라인 시집
          • a5 책 만들기
    • [Youtube] 마포구타자기
      • [mptw] JTBD
        • IKIGAI
      • [mptw] 채널 설정
        • 채널 이름 후보군
      • 시리즈 [읽는음악]
        • [읽는음악] 백로그
          • 노래 가사 콘텐츠 레퍼런스
        • ep1. 파노라마 - 이찬혁
          • 이찬혁 <ERROR>
        • ep2. 마지막 인사 (feat. 청하) - 이찬혁
        • ep3. 나의 바다에게 - 도영
        • ep4. Dattom - 백예린
        • ep5. REBEL HEART - IVE
        • ep6. Either way - IVE
        • ep7. 너와의 모든 지금 - 재쓰비(JAESSBEE)
        • ep8. 예뻤어 - DAY6
        • 6주차. 데이식스 시리즈
    • [IT] 공적인사적모임 플랫폼
      • 1. 우리 조직의 얼굴을 만들자
      • 2. 내 생에 첫 기획서 만들기 (feat. QA Driven Development)
    • [Meet] 공적인사적모임
    • [Youtube] 이상한나라의 개발자할무니
    • [Study] Disquiet PM 스터디 쿨피스
    • [IT] 서울 빵 맛집 잘알 테스트
    • [Meet] 얼리버드 모닝클럽
      • 홍보를 곁들인 2주일 운영후기
  • 잡학사전
    • 와인 원데이 클래스
    • 소설쓰기
      • <책> 소설쓰기의 모든 것 1 - 플롯과 구조
      • 유튜브 - 소설 쓰는 법
      • 강의들
      • 작가가 되려면 어떻게 해야해
    • AI
      • 생성형 AI
    • ComfyUI
      • Stable Diffusion
      • ComfyUI 준비, 설치, 설정
      • Module 구조에 대해 이해하기
      • ComfyUI
      • Core Node
    • 작사
      • 작사가 되는 법
    • 유튜브
      • 유튜버 스토리님의 부캐 성장기
      • 주언규 유튜브 초보편 (클래스101)
      • 주언규 유튜브 왕초보 편
    • 경제
      • 연금저축펀드
    • ChatGPT
    • 크롤링
      • Automatio
      • Octoparse
    • 노코드
      • 북마크 & 노코드 서비스 목록
  • PRODUCT&BUSINESS
    • Service Planning/Analysis
      • 브런치시리즈 <개발보단 고객개발>
      • baemin mart
        • 1. 시작
        • 2. 우아한형제들 & 배민상회
        • 3-1. [인터뷰] 포항에서 치킨집을 운영하시는 최사장님
        • 3-2. [인터뷰] 부산에서 족발 프렌차이즈를 운영하시는 이사장님
        • 4. <아프니까 사장이다> 커뮤니티 데이터 분석
        • 5. 문제정의 & 개선 가설
        • 6. 결론 - 역기획서
      • careerly
      • meetme
      • 배달의 민족 역기획 사례
      • 당근마켓 역기획 사례
      • 도그냥 님이 말하는 진짜 역기획
      • 도그냥의 역기획 스터디법
      • 책 <현업 기획자 도그냥의 서비스 기획 스쿨>
      • 기획서 작성하기
    • Business/Growth
      • Unsexy Business 뉴스레터에서 얻는 인사이트
      • 책 <원씽>
      • 책 <아프리카 스타트업>
      • 책 <유난한 도전>
      • 책 <함께자라기>
      • 책 <나는 돈 없어도 사업을 한다>
      • 책 <나는 장사의 신 은현장이다>
      • 책 <왜 사업하는가>
      • 책 <왜 일하는가>
      • 이제는 피칭도 유튜브로
      • 세컨드 브레인이 필요한 이유
      • 책 <타이탄의 도구들>
      • 책 <역행자>
        • <역행자> 역행자의 7단계 모델 복습
        • <역행자> 운명을 거스르는 역행자의 7단계 모델
      • 책 <월급쟁이로 시작한 38살 그녀는 어떻게 30억을 벌어 파이어족이 되었을까?>
      • 책 <파리에서 도시락을 파는 여자>
      • 책 <존리의 금융문맹탈출>
      • 책 <돈의 감각을 길러주는 경제 지식 첫걸음>
        • 금리
        • 환율
        • 주식
        • 채권
        • 부동산
        • 연금
        • 경제정책
        • 규제
        • 경제위기
    • Product-Market Fit
      • 브런치 북 <개발보단 고객 개발>
      • 책 <아이디어 불패의 법칙>
      • 고이장례연구소
      • 글쓰기로 PMF 검증하기
      • 연대 송도 캠퍼스의 40%가 사용한 서비스
      • 어웨이크코퍼레이션의 김민준 님
      • 드로우 마이 브랜드
      • 노코드로 PMF 찾는 방법
    • UI/UX
      • UX Writing Workshop
        • 4. 고객과의 관계형성 - 차별점 강화
        • 3. 비즈니스 임팩트를 만드는 글쓰기
        • 2. 후킹한 문장으로 고객 행동 이끌기
        • 1. 쉽고 정확한 문장으로 문제해결
        • What is UX Writing?
        • Reference
      • UX/UI 관련 유용한 사이트 모음
    • PM/PO
      • 책 <프로덕트 매니지먼트>
      • 책 <인스파이어드>
      • PM Wiki
      • 당신과 팀을 성장시킬 PM 직무가이드
      • PO 미신, 파랑새를 찾아서 - CPO 김용훈
      • 개발자가 생각하는 좋은 PM 나쁜 PM
      • 프로덕트 매니저는 뭐하는 사람인가
      • 토스 리더가 말하는 PO가 꼭 알아야할 개념 (2)
      • 토스 리더가 말하는 PO가 꼭 알아야할 개념 (1)
      • 책 <조직을 성공으로 이끄는 프로덕트 오너>
        • <프로덕트 오너> PO의 시간관리법
        • <프로덕트 오너> PO가 데이터 기반으로 일할 수 밖에 없는 이유
  • DATA
    • Database
      • 이 위키를 만드는데 참고한 자료들
      • 데이터 기반 의사결정
      • 데이터베이스의 종류
      • 트랜잭션과 무결성
      • 트랜잭션, 커밋, 롤백, 트랜잭션 전파
      • ERD, entity relationship diagram
      • 기본 3 - 관계, 키
      • 기본 2 - 필드, 레코드, 타입
      • 기본 1 - 엔티티, 릴레이션, 속성, 도메인
    • SQL
      • Sub Query
      • JOIN
      • 데이터 정렬셋과 유니코드
      • 자료형
      • DDL, DML
      • SELECT
      • SQL
    • MySQL
      • MSQL to MySQL Data Migration
      • MySQL Server 다운로드, 로그인
      • helpful commands
      • 문자열 자르기 SUBSTR(column, startIdx, length)
      • 특정 값을 ORDER BY 특정 값 우선 정렬 하기 (ORDER BY FIELD)
      • 이것이 MySQL이다
    • H2
      • ‼️h2 in-memory-db Table not found (this database is empty) 해결방법
  • Dev-General
    • Webmark
    • Open Source
      • 나의 첫 opensource contribution 경험기
    • Dev-Insight
      • Event
        • YOUTHCON 2022
        • INFCON 2022
      • 책 <누워서 읽는 알고리즘>
      • 책 <나는 LINE 개발자입니다>
      • 서비스에 대해 개발자가 가져야할 생각들
      • AI 시대에서 결국 살아남는 것
      • AI 시대에 개발자가 살아남는 방법
      • 주니어를 넘어서, 성장하는 개발자의 길 (인프런)
      • 아마추어와 프로의 차이
      • 개발자의 개발공부에 대하여
      • 서비스에 대해 개발자가 가져야할 생각들
      • 좋은 개발자와 인맥을 만든 노하우
      • 개발자 취업기/이직기 모음
        • 라인게임즈 백엔드 개발자 경선님
        • OKKY 미니세미나 <비전공 학원출신 SI개발자, 유명스타트업 들어간.ssul> 참석 후기
        • 비전공자에서 2억받는 아마존 엔지니어가 되기까지
        • IT 대기업 100% 합격하는 방법
  • 🏗️computer science
    • Algorithm & Data Structure
      • About this page
      • Test Review
        • Page 1
      • Big-O
        • 빅오표기법의 문제풀이
        • 피보나치 수열의 시간복잡도
      • Bit Operation
        • bit masking
      • Math
        • 합공식 / 누적합
        • 피보나치 수
        • 약수찾기
        • 소수찾기
          • 백준 1978 소수찾기
          • 백준4948 베르트랑 공준
          • 백준 8393 합
          • 백준 1929 소수구하기
        • 최대공약수 / 최소공배수
          • 백준 2824 최대공약수, BigInteger
          • 백준 2609 최대공약수, 최소공배수
        • 순열과 조합
          • 백준 15649 N과 M
        • 그 외 개념 정리
      • Recursion
        • N Queens problem
        • counting cells in a blob
        • recursion 응용 - 미로찾기
        • 순환 알고리즘의 설계
        • 순환적으로 사고하기
        • 백준 17478 재귀함수가 뭔가요
        • 백준 10870 피보나치수 5
      • Sort
        • java 에서의 정렬
        • radix sort
        • sorting in linear time
        • comparison sort 에서 최상의 시간복잡도
        • priority queue
        • heap sort
        • quick sort
        • merge sort
      • Array and List
        • 표준 라이브러리
      • Linked list
      • String
      • Stack
        • 백준 1874 스택수열
        • 백준 10828 스택 구현하기
      • Queue
        • 백준 10845 큐 구현하기
      • Heap
        • 백준 11298 절대값힙
        • 백준11279 최대힙
        • 백준1927 최소힙
      • Deque
      • Tree and Binary tree
        • Tries
        • Red-Black Tree
        • Binary Search Tree
      • Search
        • 완전 탐색
        • 이분탐색
      • Graph
        • 최단경로
        • MST 2 - prim 의 알고리즘
        • MST 1 - Kruskal 의 알고리즘
        • MST, minumum spanning tree
        • DAG, Directed Acyclic Graph
        • DFS, Depth First Search
        • BFS, Breadth First Search
      • Dynamic Programming
        • Knapsack problem
        • LCS, Longest Common Subsequence
        • matrix chain
        • 행렬 경로 문제
        • 백준 1003 피보나치 함수
        • 백준 9461 파도반 수열
        • 백준9251 LCS
      • Greedy
      • Implementation
      • LIS, Longest Increasing Subsequence
      • Two Pointer
      • Line Swipping
      • Fenwick tree
      • Backtracking
    • Computer Structure
      • 이 위키를 만드는데 참고한 자료들
      • 그래서 컴퓨터는 어떻게 동작하나요?
      • 컴퓨터의 구성
      • 컴퓨터의 역사
      • 컴퓨터 구성요소의 기능 및 이해
      • 중앙처리장치 - 마이크로 명령 - 입출력과 인터럽트
      • 중앙처리장치 - 기본 컴퓨터 프로그래밍
      • 중앙처리장치 - 프로그래밍 언어와 실행
      • 파이프라인과 벡터처리 - 데이터의 종속성 - 병렬처리와 파이프라인
      • 파이프라인과 벡터처리 - 파이프라인 구조 - 데이터/구조
      • 파이프라인과 백터처리 - 산술&명령어 파이프라인
      • 파이프라인과 벡터처리 - 파이프라인 CPU의 성능분석
      • 메모리 구조 - 메모리 시스템의 이해
      • 메모리 구조 - 효율적인 메모리 관리 정책
      • 메모리 구조 - 컴퓨터 성능 개선을 위한 메모리 관리
      • 입출력구조 - 시스템 BUS 구성 및 제어
      • 입출력 구조 - 입출력(I/O) 연결과 주소 지정
      • 입출력 구조 - 입출력 수행과 인터럽트
      • 병렬컴퓨터 구조와 성능분석 - 멀티 프로세서
      • 병렬 컴퓨터 구조와 성능 분석 - 시스템 성능 분석과 개선
    • This Is Coding Test 2021
      • 1. 출제 경향 & 파이썬 문법 부수기
      • 2. 그리디 알고리즘 & 구현
      • 3. BFS & DFS
      • 4. 정렬 알고리즘
      • 5. 이진탐색
      • 6. 다이나믹 프로그래밍
      • 7. 최단경로 알고리즘
      • 8. 기타 그래프 이론
      • 9. 코딩테스트에서 자주 출제되는 기타 알고리즘
      • 10. 개발형 코딩테스트
    • Operating System
      • 이 위키를 만드는데 참고한 자료들
      • 운영체제란, Introduction to Operating Systems
      • 컴퓨터 시스템의 구조, Structure of Computer System
      • 프로그램의 실행, Program Execution
      • 프로세스, Process
      • 쓰레드, Thread
      • 프로세스의 생성과 종료, Start and End of Process
      • 프로세스 시스템 콜과 프로세스간의 협력, System call and Interprocess Communication
      • CPU Scheduling
      • CPU Scheduling Algorithm
      • Process Synchronization Problem
      • Initial Attempts to Solve Process Synchronization Problem
      • semaphore 와 monitor 로 synchronization 해결하기
      • 데드락, Deadlock
      • 메모리 관리, Memory Management
      • Memory Allocation
      • Virtual Memory
      • Virtual Memory 2
      • File System
      • File Systems Implementation
      • Disk Management & Scheduling
    • Network
      • 이 위키를 만드는데 참고한 자료들
      • 대규모 트래픽으로 인한 서버 과부하 해결방법
      • 유선 LAN과 무선 LAN
      • 네트워크를 이루는 장치 (L1, L2 .. L7)
      • REST API
      • HTTP 매서드
      • HTTP 상태코드
      • 직렬화와 역직렬화
      • 로그인 구현방식 2. 토큰 기반 인증방식
      • 로그인 구현방식 1. 세션 기반 인증방식
      • 웹 브라우저의 캐시 - 공통점과 차이점
      • 웹 브라우저의 캐시 - 쿠키
      • HTTP header
      • 웹 브라우저의 캐시 - 세션 스토리지
      • 웹 브라우저의 캐시 - 로컬스토리지
      • browser rendering
      • HTTPS 와 TLS - TLS 핸드쉐이크
      • HTTPS 와 TLS - 암호화
      • HTTP History
      • www.naver.com 을 주소창에 입력하고 화면에 나타나기까지의 과정
      • IP 주소 - 공인 IP와 사설 IP
      • IP 주소 - Classless,Subnet Mask, Subnetting
      • IP 주소 - Classful IP Addressing
      • IP 주소 - IPv4, IPv6
      • IP 주소 - 이진수 이해하기
      • IP 주소, MAC 주소, ARP, RARP
      • 라우팅
      • TCP 4way handshake and TIME_WAIT
      • TCP 3way handshake
      • TCP/IP - internet layer
      • TCP/IP - Transport Layer
      • TCP/IP - Application Layer
      • TCP/IP - MTU, MSS, PMTUD
      • TCP/IP 4계층, OSI 7 layer
      • 네트워크의 분류 - LAN, MAN, WAN
      • 네트워크 토폴로지와 병목현상
      • 네트워크의 기초 3
      • 네트워크의 기초 2
      • 네트워크의 기초
    • Linux
      • reference
      • sudo apt-get install / uninstall
      • vim
      • linux basic command
    • Design Pattern
      • 이 위키를 만드는데 참고한 자료들
      • static 을 자주 사용하게 되었을 때의 단점
      • 자바스크립트의 class와 static
      • 프로그래밍 컨텍스트
      • 의존성 주입 vs. 전략패턴
      • flux pattern
      • Spring MVC 패턴 적용 사례
      • MVC, MVP, MVVM pattern
      • 프록시 패턴
      • 옵저버 패턴
      • 전략패턴
      • 의존성 주입과 의존 관계 역전 원칙
      • 이터레이션 패턴
      • 추상 팩토리 매소드 패턴
      • 팩토리 메소드 패턴
      • 싱글톤 패턴
      • 디자인 패턴, 라이브러리와 프레임워크의 차이
    • Programming Basic (Go)
      • 이 위키를 만드는데 참고한 자료들
      • 트랜지스터, Trangister
      • 논리소자, Logic Element
      • 튜링과 폰 노이만, Turing and Von Neumann
      • 컴퓨터의 원리, Computer Principle
      • 프로그래밍 언어, Programming Language
      • 컴파일러와 동적언어, Compiler and dynamic language
      • golang
      • hello, world
      • variable
      • variable 2
    • Base Knowledge
      • 이 위키를 만드는데 참고한 자료들
      • 신기술 도입시 고민해야할 점(feat. react.js vs. vue.js)
      • 정적 타입 시스템의 필요성
      • 도커, 컨테이너
      • 클라우드, Saas, IaaS, PaaS
      • SSO
      • RBAC
      • OAuth2.0
      • REST API 사용을 위한 인증 방법 4가지
      • API
      • Data Format - XML
      • Data Format - JSON
  • ☕Java/Spring
    • Java
      • Java Code Convention
      • Java 버전별 특징 (v1-v19)
      • java.lang.Math
      • List 4가지의 초기화 방법
      • HashMap 4가지의 정렬 방법
      • 어노테이션 프로세서 정리하기
      • Annotation Processor 로 없는 소스코드 생성하기
      • lombok 은 어떻게 동작하는 것일까?
      • 다이내믹 프록시 정리하기
      • 클래스의 프록시
      • 다이내믹 프록시
      • 프록시 패턴은 무엇인가
      • Spring Data JPA 는 어떻게 동작할까?
      • reflection api 정리
      • reflection api 이용하여 spring ioc container 만들기
      • reflection api
      • spring dependency injection 은 어떻게 동작할까
      • 바이트 코드 조작하기
      • java bytecode 를 조작해 테스트 코드 커버리지 확인하기 (feat.jacoco)
      • Class Loader
      • JVM 의 구조
      • java, jvm, jdk and jre
      • synchronized
      • java string.split(".") 오류
    • Java 8
      • 이 위키를 만드는데 참고한 자료들
      • Metaspace
      • Parallel 정렬
      • Annotation
      • CompletableFuture
      • Date and Time
      • Optional
      • Stream
      • interface의 default 메소드와 static 메소드
      • 인터페이스의 변화
      • 함수형 인터페이스
      • java 8 소개
    • Spring Framework
      • Spring 3.0 준비하기
      • 특정 매소드만 transaction 처리하기
      • 스프링 프로젝트 시작하기
      • 스프링이란 무엇인가
      • 스프링 핵심 기술의 응용
      • AOP 2
      • AOP 1
      • 서비스 추상화 2
      • 서비스 추상화 1
      • 예외
      • 템플릿
      • 테스트
      • 오브젝트와 의존관계
      • 스프링이란
    • Spring Boot
      • [Gradle]UncheckedIOException
      • java19 + spring 3.0.5 + gradle 7.4.1 에서 프로젝트 gradle 설정하기
      • [리뷰] Gradle 멀티 프로젝트 관리
      • [리뷰] 멀티모듈 설계 이야기 with Spring, Gradle
    • JPA/QueryDSL
      • querydsl 을 쓰는 이유
      • JPA querydsl에서 json array 로 된 컬럼에 조건 적용하기
      • querydsl 에서 mysql order by field() 사용하기
  • 🏰Infrastructure
    • InfraWorkshop
      • 이 위키를 만드는데 참고한 자료들
      • aws로 안정적인 인프라 만들기 2
      • aws로 안정적인 인프라 만들기 1
      • 어플리케이션 진단하기
      • 서버 진단하기
      • 부하 테스트
      • 웹 성능 개선하기
      • 웹 성능 진단하기
      • <aws로 그럴듯한 인프라 만들기> 회고와 피드백
      • aws로 그럴듯한 인프라 만들기 3 - 배포스크립트
      • aws로 그럴듯한 인프라 만들기 2 - 배포하기
      • aws로 그럴듯한 인프라 만들기 1 - 네트워크 망 구성
      • docker container
      • connection check
      • network segmentation
      • cloud 서비스를 사용한다는 것
    • AWS
      • AWS IAM
      • AWS CodePipeline 으로 배포 자동화하기 (1)
      • AWS CodePipeline 으로 배포 자동화하기 (2)
  • 🪄Test
    • TDD
      • 이 위키를 만드는데 참고한 자료들
      • [2주차] 로또 과제 강의를 듣고나서
      • [1주차] 자동차 경주 과제 강의를 듣고나서
      • TDD, 리팩토링이란?
      • 가장 쉽게 TDD 시작하는 방법
      • 의식적인 연습과 학습 테스트
      • TDD 에 집착해야하는 이유
      • 공부하는 자세
    • AssertJ
      • 이 위키를 만드는데 참고한 자료들
    • JUnit
      • 이 위키를 만드는데 참고한 자료들
      • Junit 기본 개념
  • 😎OTHERS
    • Helpful Command
      • Mac 에서 특정 포트 검색, 종료
      • crontab
    • Llibrary
    • IntelliJ
      • 내가 좋아하는 커스텀 세팅
    • GIT
      • Github ID/Token 한번 입력 후 저장하기
      • Github Actions
      • github organization private repository push 안될 때 (not found issue)
      • commands
      • git commit convention
    • Logging
      • logback + webfilter 로 로그설정
      • ‼️log4j 보안 이슈
    • Postman
      • postman 의 header에서 언더바(_) 변수 인식 안되는 현상
Powered by GitBook
On this page
  • 최단경로문제
  • 다익스트라 최단경로 알고리즘
  • 다익스트라 알고리즘의 성능분석
  • 우선순위 큐 자료구조
  • 개선된 구현방법의 성능분석
  • 플로이드 워셜 알고리즘 개요
  • 플로이드 워셜 알고리즘 동작과정 살펴보기
  • 플로이드 워셜 알고리즘 성능 분석
  • 전보 문제
  • 미래도시 문제

Was this helpful?

  1. computer science
  2. This Is Coding Test 2021

7. 최단경로 알고리즘

Previous6. 다이나믹 프로그래밍Next8. 기타 그래프 이론

Last updated 2 years ago

Was this helpful?

💡 동빈나 님의 를 보면서 공부한 내용을 정리하고 있습니다. 더 자세한 내용은 을 참고해주세요 😊 학습 도구로는 을 사용하고 있고 원본 소스코드는 동빈님의 에서 확인할 수 있고 스스로 공부한 소스코드는 에서 확인할 수 있습니다.

최단경로문제

  • 가장 짧은 경로를 찾는 알고리즘을 의미한다.

  • 다양한 문제상황

    • 한 지점 -> 다른 한 지점까지의 최단 경로

    • 한 지점 -> 다른 모든 지점까지의 최단 경로

    • 모든 지점에서 다른 모든 지점까지의 최단 경로

  • 각 지점은 그래프에서 노드로 표현하고

  • 지점 간 연결된 도로는 그래프에서 간선으로 표현한다.

다익스트라 최단경로 알고리즘

  • 특정한 노드에서 출발하여 다른 모든 노드로 가는 최단 경로를 계산한다.

  • 다익스트라 최단 경로 알고리즘은 음의 간선이 없을 때 정상적으로 동작함

    • 현실 세계의 도로(간선)은 음의 간선으로 표현되지 않는다.

    • 현실 세계의 길찾기 문제에서 사용될 수 있다!

  • 다익스트라 최단경로 알고리즘은 그리디 알고리즘으로 분류된다.

    • 매 상황에서 가장 비용이 적은 노드를 선택해 임의의 과정을 반복한다.

    • 기본적으로 길찾기 문제는 다익스트라 알고리즘을 이용하는 셈이다.

동작과정

  1. 출발 노드를 설정한다.

  2. 최단 거리 테이블을 초기화한다.

    • 자기 자신은 0으로 초기화

  3. 방문하지 않은 노드 중에서 최단 거리가 가장 짧은 노드를 선택한다.

    • 그리디 알고리즘의 유형으로 분류한다.

  4. 해당 노드를 거쳐 다른 노드로 가는 비용을 계산하여 최단 거리 테이블을 갱신한다.

  5. 위 과정에서 3번과 4번을 반복한다.

동작과정 살펴보기

  • 초기 상태

    • 그래프를 준비하고 출발노드를 설정한다.

    • 거리가 짧은 노드인 1을 선택

    • 나머지는 무한으로 초기화

  • 가장 거리가 짧은 1번 노드부터 방문하지 않은 노드까지의 최단거리값을 계산해본다.

  • 현재값과 1번노드를 거쳐서 갈때의 최소값을 비교해서 갱신할지 말지 여부를 정한다.

    • 2 : 무한대 > 0+2 = 갱신!

    • 3 : 무한대 > 0+5 = 갱신!

    • 4 : 무한대 > 0+1 = 갱신!

  • 같은 방법으로 현재 노드 중에서 가장 최단 거리가 짧은 4를 선택한다.

  • 4번을 거쳐서 가는 3번과 5번 노드의 최단거리값을 비교한다.

    • 3번 : 5 > 1+3 = 갱신!

    • 5번 : 무한 > 1+1 = 갱신!

  • 3번과 5번 모두 1->4를 거쳐서 가는 값이 최단경로에 가까우므로 값을 갱신한다.

  • 현재 노드들 중 가장 거리가 짧은 노드는 2와 5이다.

    • 어느 노드를 선택해도 상관 없지만, 일반적으로 수가 작은 노드를 선택한다.

    • 2번을 선택한다.

  • 2번노드를 거쳐 갈 수 있는 노드는 3번과 4번이다.

    • 3번 : 4 < 2+3 -> 갱신안함!

    • 4번 : 1 < 2+2 -> 갱신안함!

  • 이제 가장 짧은 노드는 5이다.

  • 5에서는 3번과 6번을 갈 수 있다.

    • 3번 : 4 > 1+1+1 = 갱신!

    • 6번 : 무한 > 1+1+2 = 갱신!

  • 3번과 6번 모두 갱신된다.

  • 남아있는 3번을 선택한다.

  • 3번에서는 2번과 6번을 갈 수 있는데 두 경우 모두 계산결과 이미 최단거리값을 가지고 있다. 따라서 갱신되지 않는다.

  • 마지막 노드는 나아갈 수 있는 노드가 없기 때문에 처리하지 않아도 된다.

특징

  • 그리디 알고리즘 : 매 상황에서 장문하지 않은 가장 비용이 적은 노드를 선택해 임의의 과정을 반복

  • 단계를 거치면서 한번 처리된 노드의 최단 거리는 고정되어 더이상 바뀌지 않는다.

    • 한 단계당 하나의 노드에 대한 최단 거리를 확실히 찾는 것으로 이해할 수 있다.

  • 다익스트라 알고리즘을 수행한 뒤에 테이블에 각 노드까지의 최단거리 정보가 저장된다.

    • 완벽한 형태의 최단 경로를 구하려면 소스코드에 추가적인 기능을 더 넣어야 한다.

간단한 구현방법

  • 단계마다 방문하지 않은 노드 중에서 최단 거리가 가장 짧은 노드를 선택하기 위해서 매 단계마다 1차원 테이블의 모든 원소를 확인(순차탐색) 합니다.

import sys
input = sys.stdin.readline
INF = int(1e9)

n, m = map(int, input().split())
start = int(input())
graph = [ [] for i in range(n+1) ]
visited = [False] * (n+1)
distance = [INF] * (n+1)


for _ in range(m):
  a, b, c = map(int, input().split())
  graph(a).append((b, c))

def get_smallest_node():
  min_value = INF
  index = 0

  for i in range(1, n+1):
    if distance[i] < min_value and not visited[i]:
      min_value = distance[i]
      index = i
  
  return index

def dijkstra(start):
  distance[start] = 0
  visited[start] = True

  for i in graph[start]:
    distance[i[0]] = i[1]
  
  for j in range(n-1):
    now = get_smallest_node()
    visited[now] = True

    for k in graph[now]:
      cost = distance[now] + j[1]
    if cost < distance[j[0]]:
      distance[j[0]] = cost

dijkstra(start);

for i in range(1, n+1):
  if distance[i] == INF:
    print('INFINITY')
  else:
    print(distance[i])

다익스트라 알고리즘의 성능분석

  • 총 O(V)번에 걸쳐서 최단 거리가 가장 짧은 노드를 매번 선형 탐색해야한다. (여기서 V는 ㅌ)

  • 전체 시간 복잡도는 O(V^2)이 된다.

  • 일반적으로 코딩 테스트의 최단 경로 문제에서 전체 노드의 개수가 5,000개 이하라면 이 코드로 문제를 해결할 수 있다.

    • 5000 * 5000 = 25,000,000

    • python 에서 1초당 연산횟수 평균 : 20,000,000

    • 하지만 노드의 개수가 10,000개를 넘어가는 문제라면 어떻게 해야할까?

우선순위 큐 자료구조

  • 우선순위가 가장 높은 데이터를 가장 먼저 삭제하는 자료구조

  • 예를 들어서 여러개의 물건 데이터를 자료구조에 넣었다가 가치가 높은 물건 데이터부터 꺼내서 확인해야하는 경우에 우선순위 큐를 이용할 수 있다.

    • python, C++, Java 를 포함한 대부분의 프로그래밍 언어에서 표준 라이브러리 형태로 지원한다.

    • 자료구조 : 추출되는 데이터

    • stack : 가장 나중에 삽입된 데이터

    • queue : 가장 먼저 삽입된 데이터

    • priority queue : 가장 우선순위가 높은 데이터

      • heap

힙 Heap

  • 우선순위 큐를 구현하기 위해서 사용하는 자료구조 중 하나이다.

  • 최소 힙과 최대 힙이 있다.

  • 다익스트라 최단경로 알고리즘을 포함해서 다양한 알고리즘에서 사용된다.

  • 구현방식

    • 리스트

      • 삽입시간 : O(1)

      • 삭제시간 : O(N)

    • 힙 :

      • 삽입시간 : O(logN)

      • 삭제시간 : O(logN)

# 최소 힙
import heapq

def heapsort(iterable):
  h = []
  result = []

  for i in iterable:
    heapq.heappush(h, i)

  for i in range(len(h)):
    result.append(heapq.heappop(h))

  return result

array = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
result = heapsort(array)
print(result)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 최대 힙
import heapq

def max_heap(iterable):
  h = []
  result = []

  for i in iterable:
    heapq.heappush(h, -i)

  for i in range(len(h)):
    result.append(-heapq.heappop(h))

  return result

array = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
result = max_heap(array)
print(result)
# [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

다익스트라 알고리즘의 개선된 구현방법 (feat. heap)

  • 단계마다 방문하지 않은 노드 중에서 최단 거리가 가장 짧은 노드를 선택하기 위해서 힙(heap) 자료구조를 이용함

  • 다익스트라 알고리즘이 동작하는 기본 원리는 동일

    • 현재 가장 가까운 노드를 저장해놓기 위해서 힙 자료구조를 추가적으로 이용한다.

    • 현재의 최단 거리가 가장 짧은 노드를 선택해야 하므로 최소 힙을 사용한다.

  • java

    • priority queue library 이용하기

    • offer(), poll()

import sys
import heapq

input = sys.stdin.readline
INF = int(1e9)

n, m = map(int, input().split())
start = int(input())
graph = [[] for i in range(n+1)]
distance = [INF] * (n+1)

for _ in range(m):
  a, b, c = map(int, input().split())
  graph[a].append((b, c))

def dijkstra(start):
  q = []

  heapq.heappush(q, (0, start))
  distance[start] = 0

  while q:
    dist, now = heapq.heappop(q)

    if distance[now] < dist:
      continue

    for i in graph[now]:
      cost = dist + i[1]
      if cost < distance[i[0]]:
        distance[i[0]] = cost
        heapq.heappush(q, (cost, i[0]))

dijkstra(start)

for i in range(1, n+1):
  if distance[i] == INF:
    print('INFINITY')
  else:
    print(distance[i])

개선된 구현방법의 성능분석

  • 힙 자료구조를 이용하는 다 익스트라 알고리즘의 시간 복잡도는 O(ElogV)

  • 노드를 하나씩 꺼내 검사하는 반복문은 노드 개수 V이상의 횟수로는 처리되지 않는다.

    • 결과적으로 현재 우선순위 큐에서 꺼낸 노드와 연결된 다른 노드들을 확인하는 총 횟수는 최대 간선의 개수(E)만큼 연산이 수행될 수 있다.

  • 직관적으로 전체 과정은 E개의 원소를 우선순위 큐에 넣었다가 모두 빼내는 연산과 매우 유사함

    • 시간 복잡도를 O(ElogV) 로 판단할 수 있다.

    • 중복 간선을 포함하지 않는 경우에 이를 O(ElogV) 로 정리할 수 있다.

      • O(ElogE) -> O(ElogV^2) -> O(2ElogV) -> O(ElogV)

플로이드 워셜 알고리즘 개요

  • 모든 노드에서 다른 모든 노드까지의 최단 경로를 모두 계산한다

  • 플로이드 워셜 알고리즘은 다익스트라 알고리즘과 마찬가지로 단계별로 거쳐 가는 노드를 기준으로 알고리즘을 수행한다.

    • 다만 매 단계마다 방문하지 않은 노드 중에서 최단 거리를 갖는 노드를 찾는 과정이 필요하지 않다.

  • 플로이드 워셜은 2차원 테이블에 최단 거리 정보를 저장함

  • 플로이드 워셜 알고리즘은 다이나믹 프로그래밍 유형에 속한다.

  • 각 단계마다 특정한 노드 K를 거쳐 가는 경우를 확인한다.

    • a->b로 가는 최단 거리보다 a->k->b 가 더 짧은지 검사한다.

플로이드 워셜 알고리즘 동작과정 살펴보기

  • 현재 1번 노드를 거쳐가는 경우를 고려하기에 1번행, 1번열과 자기 자신으로 향하는 케이스들은 모두 갱신대상에서 제외된다.

  • 2번, 3번, 4번의 경우를 모두 같은 방식으로 고려한다.

INF = int(1e9)

n, m = map(int, input().split())
graph = [[INF] * (n+1) for _ in range(n+1)]

# 자기 자신에게 가는 비용은 0으로 초기화
for a in range(1, n+1):
  for b in range(1, n+1):
    if a == b:
      graph[a][b] = 0

# 간선정보 입력받기
for _ in range(m):
  a, b, c = map(int, input().split())
  graph[a][b] = c


for k in range(1, n+1):
  for a in range(1, n+1):
    for b in range(1, n+1):
      graph[a][b] = min(graph[a][b], graph[a][k]+graph[k][b])


for a in range(1, n+1):
  for b in range(1, n+1):
    if graph[a][b] == INF:
      print('INFINITY', end=" ")
    else:
      print(graph[a][b], end=" ")
  print()

플로이드 워셜 알고리즘 성능 분석

  • 노드 개수가 N개일 때 알고리즘상으로 N번의 단계를 수행

    • 각 단계마다 O(N^2) 의 연산을 통해 현재 노드를 거쳐 가는 모든 경로를 고려한다.

  • 따라서 플로이드 워셜 알고리즘의 총 시간 복잡도는 O(N^3)

    • 노드의 개수가 적을때에 주로 사용하고 (500개 이하)

    • 노드 개수가 많을 때는 다익스트라 알고리즘을 사용한다.

전보 문제

문제

  • 어떤 나라에 N개의 도시가 있음. 도시 간에는 통로로 연결되어있어서 메시지를 보내고 받을 수 있음

  • 어느날 C도시에서 위급상황이 발생했다. 도시 C의 위급사항을 최대한 많은 도시에 알리고자 한다.

  • 이 도시에서 출발하여 각 도시 사이에 설치된 경로를 거쳐 최대한 많이 퍼져나가도록 한다.

  • 이때 도시 C에서 보낸 메시지를 받게 되는 도시는 총 몇 개이며 모든 도시들이 메시지를 받는 데 걸리는 시간은 얼마인지 구하라!

  • 입력조건

    • 첫째줄

      • 도시 개수 N (1이상 30,000 이하)

      • 통로개수 M (1이상 200,000 이하)

      • 메시지 보내고자 하는 도시 C (1이상 N이하)

    • 둘째줄 ~ M+1

      • X, Y, Z 공백으로 나뉘어 입력됨

      • 각각 출발도시, 도착도시, 메시지가 전달되는 시간

  • 출력조건

    • 도시 C의 메시지를 받는 총 도시의 개수

    • 총 걸리는 시간을 공백으로 구분하여 출력하도록 함

해결방법

  • 한 도시에서 다른 도시까지의 최단 거리 문제

  • N, M의 범위가 꽤 크므로 우선순위큐 활용한 다익스트라 알고리즘으로 구현을 해야한다!

import heapq
import sys

input = sys.stdin.readline
INF = int(1e9)

n, m, c = map(int, input().split())
graph = [[] for _ in range(n+1)]
distance = [INF] * (n+1)

for _ in range(m):
  x, y, z = map(int, input().split())
  graph[x].append((y, z))

def dijkstra(start):
  q = []

  heapq.heappush(q, (0, start))
  distance[start] = 0

  while q:
    dist, now = heapq.heappop(q)

    if distance[now] < dist:
      continue
    
    for i in graph[now]:
      cost = dist + i[1]
      if cost < distance[i[0]]:
        distance[i[0]] = cost
        heapq.heappush(q, (cost, i[0]))

dijkstra(c)

print(distance)

total_num_of_cities = 0
max_distance = 0

for i in distance:
  if i == INF:
    continue
  
  total_num_of_cities += 1
  max_distance = max(max_distance, i)

# 출발지인 C를 제외하고 출력
print(total_num_of_cities -1, max_distance)

# 3 2 1
# 1 2 4
# 1 3 2
# distance = [1000000000, 0, 4, 2]
# 2 4

미래도시 문제

문제

  • 미래도시에는 1번부터 N번까지의 회사가 있다.

  • 특정 회사끼리는 서로 도로를 통해서 연결되어있고 연결된 두 회사는 양방향으로 이동이 가능하다.

  • 도시 간의 거리는 1이다.

  • 판매원 A씨는 1번회사에 있으며 X번 회사에 방문해 물건을 판매하고자 한다.

  • 가는 길에 소개팅 상대를 만나기 위하여 K번 회사를 들렀다가 가려고 한다. (1 -> K -> X)

  • 판매원 A씨가 가능한 한 빠르게 이동하고자 할 때, 이동하게 되는 최소 시간을 계산해라!

  • 입력조건

    • 첫째줄

      • N, M 공백 구분 (N과 M은 1이상 100이하)

    • 둘째줄 ~ M+1

      • 연결된 두 회사의 정보가 공백으로 구분되어 나열됨

    • M+2 째 줄

      • X 와 K가 공백으로 구분되어 나열됨

  • 출력조건

    • 최소 이동시간을 출력한다.

    • 도달할 수 없다면 -1 출력

해결

  • N이 최대 100이하이므로 플로이드 워셜 알고리즘을 이용하여 효율적으로 계산할 수 있다.

  • 플로이드 알고리즘 수행 후 1K 최단거리 + KX 까지의 최단거리 출력하면 정답인정!

INF = int(1e9)

n, m = map(int, input().split())
graph = [[INF] * (n+1) for _ in range(n+1)]

for a in range(1, n+1):
  for b in range(1, n+1):
    if a == b:
      graph[a][b] = 0

for _ in range(m):
  a, b = map(int, input().split())
  graph[a][b] = 1
  graph[b][a] = 1

x, k = map(int, input().split())

for k in range(1, n+1):
  for a in range(1, n+1):
    for b in range(1, n+1):
      graph[a][b] = min(graph[a][b], graph[a][k]+graph[k][b])
  
distance = graph[1][k] + graph[k][x]

if distance == INF:
  print(-1)
else:
  print(distance)

# 5 7
# 1 2
# 1 3
# 1 4
# 2 4
# 3 4
# 3 5
# 4 5
# 4 5
# 3

🏗️
이코테 2021 강의 몰아보기
이것이 취업을 위한 코딩 테스트다 with 파이썬
리플렛
Github
Github
자세한 설명 참고하기
자세히 설명보기
다익스트라 최단 경로 알고리즘
다익스트라 최단 경로 알고리즘