목록분류 전체보기 (297)
가수면
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/ExRQx/btsz7QP7E62/GVAm2ofxD2w8bkuGBAsosk/img.png)
https://tanstack.com/query/latest/docs/react/guides/migrating-to-v5#callbacks-on-usequery-and-queryobserver-have-been-removed Migrating to TanStack Query v5 | TanStack Query Docs useQuery and friends used to have many overloads in TypeScript - different ways how the function can be invoked. Not only this was tough to maintain, type wise, it also required a runtime check to see which type the fir..
그래프 내 특정 노드와 그래프 내 존재하는 모든 노드들 간의 각각 최단 거리를 구하는 알고리즘 원리 1. 초기값 세팅. (기준 노드를 0으로 놓고 나머지 노드들까지의 거리를 inf로 설정) 2. 그래프를 순회하며 순회한 노드들을 우선 순위 큐에 거리가 짧은 순으로 쌓음 3. 하나씩 dequeue하면서 해당 노드까지의 거리로 inf를 수정함 4. dequeue한 노드와 연결된 노드들을 우선 순위 큐에 다시 거리가 짧은 순으로 추가 5. 3번의 과정을 반복하면서 중복된 노드들이 있다면 거리값을 더 작은 값으로 수정 (ex. A->b까지 5인데 A->C->B거리가 3이라면 B의 값은 3으로 교체) 6. 우선 순위 큐를 사용하면 우선 순위가 떨어지는(거리가 먼) 노드들의 계산은 뒤로 갈수록 스킵되기에 빠른 계산..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/2SjEA/btsz5mOnHRK/s39VjoVS34iMuNao45lL40/img.png)
모든 경우의 수를 놓고 최적의 경우를 고른다기보다는 각 단계에서 최적의 경우를 고르는 전략임 그렇기 때문에 최적의 경우가 아닌 결과가 도출될 수 있음 (탐욕이라는 말이 정말 적절하다...) 문제1: 동전 문제 지불해야 하는 값이 4720원 일 때 1원 50원 100원, 500원 동전으로 동전의 수가 가장 적게 지불하시오. coin_list = [500, 100, 50, 1] def min_coin_count(value, coin_list): total_coin_count = 0 details = list() coin_list.sort(reverse=True) for coin in coin_list: coin_num = value // coin total_coin_count += coin_num value..
이진 탐색 def binarySearch(data, searchValue): if len(data) == 1 and searchValue == data[0]: return True if len(data) == 1 and searchValue != data[0]: return False if len(data) == 0: return False medium = len(data) // 2 if searchValue == data[medium]: return True else: if searchValue > data[medium]: return binarySearch(data[medium + 1:], searchValue) else: # 리스트 슬라이싱에서 [:medium]는 medium을 포함하지 않음 ret..
기준점(pivot 이라고 부름)을 정해서, 기준점보다 작은 데이터는 왼쪽(left), 큰 데이터는 오른쪽(right) 으로 모으는 알고리즘 왼쪽(left), 오른쪽(right)은 재귀용법을 사용해서 왼쪽(left) + 기준점(pivot) + 오른쪽(right) 을 리턴함 def quickSort(data): if len(data) data[index]: left.append(data[index]) else: right.append(data[index]) return quickSort(left) + [pivot] + quickSort(right) list comprehension을 적용 def quickSort(data): if len(data) item ] right = [ item for item in..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/CPOk1/btsz1TzoeKr/4DpGPY548jvUv3ug8Q3In1/img.png)
상향식 접근법으로, 가장 최하위 해답을 구한 후, 이를 저장하고, 해당 결과값을 이용해서 상위 문제를 풀어가는 방식Memoization 기법을 사용함 모든 경우의 수를 완전 탐색할 때 사용 하위의 문제들이 중복되어 재활용되는 특징이 있음 대표 예시 - 피보나치 수열 def fibo_dp(num): cache = [ 0 for index in range(num + 1)] cache[0] = 0 cache[1] = 1 for index in range(2, num + 1): cache[index] = cache[index - 1] + cache[index - 2] return cache[num] 문제 2×n 크기의 직사각형을 1×2, 2×1 타일로 채우는 방법의 수를 구하는 프로그램을 작성하시오. (1 ≤ ..
예시 배열 - [4, 3, 1, 2] 1회차 - 0 vs 1부터 가장 작은 값 [1, 3, 4, 2] 2회차 - 1 vs 2부터 가장 작은 값 [1, 2, 4, 3] 3회차 - 2 vs 3부터 가장 작은 값 [1, 2, 3, 4] 턴 수 - length - 1 비교값 - (턴 수 - 1)탐색 시작값 - (턴 수) 정리 1. length -1만큼 반복문 2. 1번 안에 전체를 탐색하는 중첩 반복문 (탐색 시작값부터 length -1까지) 3. 제일 낮은 숫자의 인덱스 저장 4. 비교값과 제일 낮은 숫자 비교 후 교체 def selectionSort(data): for index in range(len(data) - 1): lowestIndex = index for index2 in range(index +..
예시 배열 - [9, 3, 2, 5] 1회차 - 1과 0을 비교 후 교체 [3, 9, 2, 5] 2회차 - 2와 1을 비교 후 교체 [3, 2, 9, 5], 1과 0을 비교 후 교체 [2, 3, 9, 5] 3회차 - 3과 2를 비교 후 교체 [2, 3, 5, 9], 2과 1를 비교 후 교체 [2, 3, 5, 9], 1과 0을 비교 후 교체 [2, 3, 5, 9] 턴 수 - length - 1 각 턴의 순회 횟수 - length - 1 비교 후 뒤에 값이 더 클 경우 반복문 종료 앞에 회차에서부터 거슬러오면서 정렬을 했기 때문에 비교 시 값이 더 큰 경우 앞에 값들은 이미 정렬된 값들이라는 확신을 할 수 있음 정리 1. length -1만큼 반복문 2. 1번 안에 index + 1(시작), 0(1 까지),..
2개일 경우 0 1 5 2 0과 1을 비교 3개일 경우 0 1 2 5 2 1 0과 1을 비교, 1과 2를 비교 0 1 2 2 1 5 한번 더 해야함. 4개일 경우 - 0과 1을 비교, 1과 2를 비교, 2와 3을 비교 x 3 순회 횟수 = length -1 반복 횟수 = length -1 기본 로직 1. length -1만큼 반복문 2. 1번 안에 length - 1만큼 중첩 반복문 3. 비교 후 바꿔주는 로직 반복 시 불필요한 순회 빼기 순회할 때마다 해당 순회차의 마지막 값은 확실하게 정렬된 값임 순회차 = i i = 1일 때 반복 횟수 - 1 i = 2일 때 반복 횟수 - 2 반복횟수 = length - 1 - i 순회 시 스왑이 한번도 일어나지 않았을 경우 조기 종료 정리 1. length -1만..
반복문 한 줄로 표기list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]test = [i for i in list]test// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]test = [ 0 for index in range(6)] // test = [0] * 6test// [0, 0, 0, 0, 0, 0] 반복문과 조건문 합쳐서 사용하기if node in visited // visited에 node가 있으면if node not in visited // visited에 node가 없으면 comprehension [i for i in mylist (조건문)]list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]test = [i for i in list i..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/MNSIs/btszUdkj14C/thjTSIEaM2LylI8K3G9Knk/img.png)
의문의 발단은 스터디 톡방에 올라온 코드로부터 시작되었다. 아래는 화면이 md사이즈일 때 요소들이 보이고 안 보이는 것을 조절한 반응형 레이아웃 코드다. 코드와 함께 올라온 주제는 메인 페이지에서 저 무거운 컴포넌트를 전부 불러오고 있는데 좋은 방법이 없느냐. 나는 아래 display: none요소들을 컴포넌트로 묶어 react lazy를 사용할 것을 권했다. 레이지 로딩을 쓰면 저런 식으로 구성해도 모바일 뷰가 되기 이전에 안 불러오는 것이 맞는지 걱정된다는 말이 돌아왔다. 나는 2가지 이유를 들어 안 불러와질 것이라 답변했다. 1. '반환된 구성 요소를 처음 렌더링하려고 시도할 때까지 호출하지 않습니다.' (리액트 공식 문서에 나와있는 lazy의 설명) 2. display: none이 적용된 요소는 ..
z-index를 사용함에 있어 조건과 규칙을 정리한다. 1. Stacking Context 생성 먼저 z-index를 적용하기 위해선 relative, absolute 등과 같은 position속성을 지정해 Stacking Context를 생성해줘야 한다. Stacking Context 생성 그러면 Z축 공간을 사용할 수 있게되며, 해당 페이지에 생성된 Stacking Context의 z-index를 비교하여 순서대로 합성하게 된다. 이때 position의 속성의 상하 관계는 없다. 2. 자식 요소들은 생성된 부모 Stacking Context에 종속된다. A컴포넌트 - z-index: 20 B컴포넌트 - z-index: 10 이 경우 A컴포넌트가 위로 올라오게 된다. (아래 예시에서는 형제 요소로 했지..
들어가기 전 필요한 기본 지식 strokeDasharray - 점선의 길이와 간격 (길이와 간격을 각각 전체 선 길이로 설정할 경우 선이 감춰진다.) strokeDashoffset - 선이 시작되는 위치 (선의 전체 길이 = 선의 시작점, 0 = 끝점 ) 원리는 다음과 같다. 1. svg를 숨김 2. svg가 보여지는 순간을 0, svg가 완전히 다 지나면 1이 되는 비율값을 구한다. 3. strokeDashoffset에 비율값을 적용해 스크롤을 내릴 때마다 마치 선이 그려지는 듯한 효과를 낸다. 구현 과정 1. ref 설정 svg가 그려지는 구역의 ref와 svg 길이의 ref를 저장한다. interface Props { containerRef: MutableRefObject; } const Curve..
애니메이션 순서 animation-name 예: slideIn, fade, bounce animation-duration 예: 2s, 500ms animation-timing-function (애니메이션 속도 곡선) 예: linear, ease, ease-in, ease-out, ease-in-out, cubic-bezier(...), steps(...) animation-delay 예: 1s, 300ms animation-iteration-count (반복) 예: 1, 2, 5, infinite animation-direction (애니메이션의 재생 방향) 예: normal, reverse, alternate, alternate-reverse animation-fill-mode 예: none, forw..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/1CSrK/btssZeQYih7/wLZOx9NK91qkL5ilQKIJxk/img.png)
프론트 1. mkcert설치 https://github.com/FiloSottile/mkcert#installation GitHub - FiloSottile/mkcert: A simple zero-config tool to make locally trusted development certificates with any names you'd lik A simple zero-config tool to make locally trusted development certificates with any names you'd like. - GitHub - FiloSottile/mkcert: A simple zero-config tool to make locally trusted developmen... githu..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/dePSgj/btssABrpny4/qPvKohwk9Grclda7d4mmUk/img.png)
일반적인 페이지네이션 혹은 슬라이드를 구현한다고 한다면 다음과 같은 준비물이 필요할 것이다. 1. 한 번에 몇 개의 요소를 렌더링 시킬 건지 렌더링시킬 요소 개수 2. 전체 배열을 1번으로 나눈 페이지 수 3. slice 자, 그렇다면 길이가 제각각인 현재 나의 키워드의 개수가 영역을 넘어가면 어떻게 처리할 것인가..! 기능 구현에 있어 가장 큰 문제는 한 페이지에 몇 개가 렌더링되는지가 키워드 길이에 따라서 랜덤하게 결정된다는 것이었다. 레퍼런스를 어느 곳에서도 찾을 수 없었기에 나는 차근차근 접근해보았다. 로직 구상 먼저 구현에 있어 가장 중요한 것은 영역 안에 몇 개가 렌더링되는지 카운팅하는 것이다. 현재 로직은 flex-wrap과 overflow hidden 속성을 이용해 레이아웃을 구현한 상태다..
리팩토링 핵심 1. 기본 원칙 목표 코드의 가독성 향상 복잡성 감소 유지보수성 향상 확장성 향상 지향점 누구나 잘 알아볼 수 있는가 (성능 최적화 신경쓰지 않고 코드를 다루기 쉽게 만드는 것(가독성)에 집중.) 한 가지 역할만 수행하는가 재사용 가능한 단위인가 기능의 원하는 부분만 수정할 때 용이한가 너무 미래 지향적인 코드 x (점진적 확장) 매개 변수로 불리언 타입 받아 분기 처리하는 함수 지양 되도록 매개 변수 없는 함수 지향 모듈 간 독립성 유지 - 변수(어떤 데이터) / 함수(어떤 일) / 모듈(어떤 책임) 명확한 분리 리팩토링 중 피해야 할 행동 기능의 변경이나 추가: 기능 변경이나 추가는 리팩토링 과정에서의 핵심 목표가 아닙니다. 리팩토링은 코드의 내부 구조를 개선하는 것에 초점을 맞추어야 ..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/btFzJv/btsrCQQFwIG/gktdN3HEWrthCrynZ7Sho1/img.png)
https://docs.github.com/ko/actions/using-workflows/about-workflows 워크플로 정보 - GitHub Docs 트리거, 구문 및 고급 기능을 포함하여 GitHub Actions 워크플로에 대한 개략적인 개요를 알아봅니다. docs.github.com Next에서 Jest를 이용한 깃허브 액션 설정 1. 루트 경로에 .github/workflows 폴더 생성 2. 이름.yml 파일 생성 3. 워크 플로우 설정 // .github\workflows\main.yml name: CI on: [push, pull_request] // 워크플로우 트리거 이벤트 설정 jobs: build-and-test: runs-on: ubuntu-latest// ubuntu 최신 ..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/bjqx9m/btsrDKCD67n/kwCvmxqtMKC2rSIQC7NII1/img.png)
모노레포란 한 저장소 안에 여러 개의 프로젝트 혹은 여러 개의 package.json이 존재하는 레포지토리를 말한다. 예시 1) 프로젝트 이름/ |-- 부속 라이브러리/ | |-- node_modules/ | |-- ... | |-- package.json |-- node_modules/ |-- public/ |-- src/ |-- ... |-- package.json 예시 2) 저장소 이름/ |-- 프로젝트1/ | |-- node_modules/ | |-- ... | |-- package.json |-- 프로젝트2/ | |-- node_modules/ | |-- ... | |-- package.json 이 경우 배포를 진행하면 클라우드가 루트 경로에 위치한 package.json만 인식해 설치하기 때문..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/ukWgE/btsqJTnxKl8/SkRFKvK24PrGfnofHA4eM1/img.png)
넥스트에서 Link태그나 useRouter를 이용해 경로 이동하는 테스트를 시도하면 "Not implemented: navigation" 같은 오류가 발생한다. await userEvent.click(screen.getByText("Tech")); expect(window.location.pathname).toEqual("/tech"); 이것은 React Testing Library환경에서 Next를 사용하는 데 오는 문제다. 기본적으로 RTL와 Jest는 리액트 환경에 초점이 맞춰져있으며, Next에서 제공하는 useRouter와 Link태그는 Next 자체에서 제공하는 유틸리티다. 즉, RTL에 없는 기능을 사용하려니 문제가 발생하는 것이다. 리액트에서처럼 react-router-dom에서 제공하는 ..