728x90

서버에서 두 개 이상의 응답을 보내려 하는 경우 나타나는 에러다. 

 

나는 아무리봐도 res. 응답이 중복되지 않았는데 뭐지 했더니

res.send().json 이렇게 있지도 않은 메서드로 응답했던 것~!

 

res.status(200).json() 으로 바꿔주었더니 해결되었다. 

728x90
728x90

이진탐색은 정렬된 배열에서 특정한 값을 찾는 알고리즘이다

배열의 중간값을  기준으로 값을 찾고 

찾고자하는 값과 중간값을 비교하고 탐색범위를 반으로 줄인다

탐색범위가 없을 때까지 반복한다

 

chatqpt에거 물어본 이진탐색 

 

def binary_search(arr, target):   #정렬, 찾고자 하는 값이 인수로 들어감
    left = 0  #arr의 맨왼쪽인덱스
    right = len(arr) - 1 #arr의 맨오른쪽인덱스

    while left <= right:  #비교했을 때 오른쪽이 작을때까지 반복 (즉 탐색할 배열이 없을때까지)
        mid = (left + right) // 2

        if arr[mid] == target: #가운데데 인덱스의 값이 찾고자하는 값이면 
            return mid   #가운데인덱스를 리턴
        elif arr[mid] < target: #찾고자하는 값보다 가운데 인덱스의 값이 작으면
            left = mid + 1  #맨왼쪽, 첫번째 인덱스가 중간값부터 시작됨 (시작점을 바꿔서 기존 정렬을 반으로나누는것 뜻)
        else:
            right = mid - 1 #맨오른쪽, 마지막 인덱스가 중간값부터 시작됨(시작점을 바꿔서 기존 정렬을 반으로나누는것 뜻

    return -1 #값을 못찾으면 -1 내보냄 너가 찾는 값없어~~

이진 탐색은 검색, 정렬, 최솟값/최댓값 찾기 등 다양한 문제에서 사용됩니다.
이진 탐색은 탐색할 배열이 정렬되어 있어야 한다는 조건이 있지만, 이 조건을 만족한다면 빠른 탐색을 수행할 수 있는 알고리즘입니다. 이진 탐색은 효율적인 탐색을 위해 항상 고려해야 할 알고리즘 중 하나입니다.

728x90
728x90

정렬은 주어진 데이터를 일정하게 재배열하는 것이다. 

데이터를 재배열하는 정렬 종류는 다양하다

 

 

1) 버블 정렬

비교해서 큰 데이터를 오른쪽으로 보내서 재배열하는 방법

전체 배열를 모두 조회해서 데이터를 비교한다. -> 반복 : 큰데이터에는 효율적이지 못한 알고리즘이다.

2) 선택 정렬

가장 작은 최솟값을 골라서 맨앞에 보내는 식으로 재배열한다. 

가장 작은 최솟값 고르려면 전체 배열을 모두 조회해야한다. -> 반복 : 마찬가지로 큰데이터에는 효율적이지 못한 알고리즘

 

이처럼 정렬 알고리즘의 성능을 평가하는데에는 주로 '시간복잡도' 개념이 쓰인다. 

시간복잡도란 알고리즘 수행시간이 입력한 값에 따라 얼마나 증가하는지를 나타내는 지표이다. 

출처 : https://junghyun100.github.io/Time-Complexity/
출처: https://wikidocs.net/34790

 

 

 

3) 힙정렬

힙 - 더미, 데이터를 특정한 형태로 쌓아올리는 것을 의미. 

노드간의 관계를 나타내는 이진트리구조에서 힙 구조가 나타난다. 

기본 리스트를 힙정렬로 만들려면 일단 최대 혹은 최소값을 가지는 루트를 설정하고 

루트를 기준으로 값(노드)를 정렬한다. 

 

 

4) 삽입정렬

삽입정렬은 버블정렬과 비슷해보이지만 

모든 데이터를 조회하며 비교하는 버블정렬과 달리

이미 정렬된 부분과 정렬되지 않은 부분을 유지하며

정렬된 부분에는 요소를 삽입하여 배열하므로 버블 정렬보다 효율적인 정렬이다.

 

5) 퀵 정렬

기준을 세워 분할한다(보통 중간값을 기준으로 함).작은 요소는 왼쪽, 큰 요소는 오른쪽에 위치한다.

분할하고 배열하고를 재귀적으로 반복 후 합쳐서 정렬.

 

6)병합 정렬

리스트를 반으로 나눈다. 리스트 크기가 1이하가 될때까지 반으로 나눈다.

나눈 작은 리스트를 정렬한다. 나눴던 리스트의 가장 작은 요소를 비교해서 

작은 순서대로 병합한다. 

입력크기와 상관없이 일정한 시간복잡도를 가진다. 

 

 

 

 

 

 

728x90
728x90

위에서 아래로 일방향, 계층구조인 트리와 다르게

그래프는 어떤 노드들과도 연결될 수 있다.

 

마치 지하철 노선도 처럼

 

다양한 그래프 종류들!

출처:&nbsp;https://laboputer.github.io/ps/2017/09/29/graph/

 

그래프는

연결점(노드)과 연결점 사이를 잇는 간선으로 이루어져 있다.

 

그래프는 표현하는 방법은

크게 3가지가 있다. 

 

1. 인접리스트 (adjacency list)

모든 노드에 연결된 노드들을 순서대로 기록한 리스트

연결된 노드만 기록한다. 

 

파이썬에서 딕셔너리를 써서 키 : 값으로 적어서 사용 많이 함. 

출처:&nbsp;https://www.lavivienpost.net/graph-implementation-as-adjacency-list/

const graph = [[2,3],[1,3],[1,2,4],[3]]

2. 인접행렬 (adjacency matrix)

그래프에서 어느 연결점(노드)들이 변(간선)으로 연결되었는지 나타내는 정사각 행렬

출처 : 위키백과

가로 123456 세로 123456 노드

(가로,세로)
(1,1) 자기 자신은 연결할 수 없어서 0

(1,2) 연결되어서 1 임

무방향 그래프에서  인접행렬은 다음과 같이 대칭이다.

 

const graph = [

      [0, 1, 0, 0, 1, 0],     

   [1, 0, 1, 0, 1, 0],  

   [0, 1, 0, 1, 1, 0],  

 [0, 0, 1, 0, 1, 1],

 [1, 1, 0, 1, 0, 0],

 [0, 0, 0, 1, 0, 0]

]

 

3. 암시적 그래프

그래프의 정점과 간선을 직접적으로 표현하지 않고, 

필요한 상황에서 동적으로 그래프의 일부 또는 전체를 생성하거나 탐색하는 방식이다.

연결표시를 하지 않아도 주변이 연결되어있음을 암시적으로 알 수 있는 경우!

ex) 미로 찾기 문제

 

 

 

DFS(깊이우선탐색)  vs BFS(너비우선탐색)

출처: 나무위키

 

DFS(깊이우선탐색)

노드의 간선을 타고 깊이를 우선적으로 탐색함

스택 또는 재귀함수로 구현

 

스택: 쌓아놓은 더미. 마지막으로 넣은 걸 먼저 꺼낼 수 있음.

(

왼쪽 살펴서 있으면 깊이 끝까지 탐색 후 오른쪽.

오른쪽 노드가 다시 첫번째 노드가 되어서 왼쪽 깊이 탐색 후 오른쪽.

반복되어 재귀함수로 구현 가능. )

 

 

BFS(너비우선탐색)

전체 너비, 행순으로 탐색함

큐로 구현

 

큐: 버스 앞에 줄선 사람. 먼저 선 사람이 버스 탈 수 있음.

 

 

코드는 차후에 정리해보겟음..

 

컴백함. 정리해보겠음

 

 

--------------------

 

chatgpt한테 물어봄

 

DFS(깊이우선탐색) 알고리즘 코드구현

 

 

def dfs(graph, start, visited): #인자에 그래프, 시작노드, 방문한 노드 집합
    visited.add(start)  # 현재 노드를 방문 처리
    print(start, end=' ')
    
    # 현재 노드와 인접한 노드들을 순회
    for adjacent_node in graph[start]:
        if adjacent_node not in visited: #만약에 방문하지 않은 노드라면 
            dfs(graph, adjacent_node, visited) #그 노드를 시작노드로 해서 재귀함수 실행 -> 현재노드를 방문처리~ 반복

# 그래프를 인접 리스트로 표현한 예시
graph = {
    'A': ['B', 'C'],
    'B': ['A', 'D', 'E'],
    'C': ['A', 'F'],
    'D': ['B'],
    'E': ['B', 'F'],
    'F': ['C', 'E']
}

visited = set()  # 방문한 노드를 저장하기 위한 집합

print("깊이 우선 탐색 결과:")
dfs(graph, 'A', visited)

그래프의 모든 노드를 깊이를 우선하여 탐색하는 DFS는 

재귀함수 또는 스택으로 구현될 수 있다.

여기서는 재귀함수로 구현됨

 

코드풀이~

 

시작노드를 방문처리하고

그 시작노드의 인접노드가 방문하지 않은 노드라면

해당 노드를 다시 시작노드로 설정해서 재귀함수~ (다시 그 시작노드로 방문처리하고 반복)

 

스택으로 구현한 코드

def dfs(graph, start):
    visited = set()  # 방문한 노드를 저장하기 위한 집합
    stack = [start]  # 탐색할 노드를 저장하기 위한 스택

    while stack:
        node = stack.pop()  # 스택의 가장 위에 있는 노드를 가져옴

        if node not in visited:
            visited.add(node)
            print(node, end=' ')

            # 인접한 노드들 중에서 방문하지 않은 노드를 스택에 추가
            for adjacent_node in graph[node]:
                if adjacent_node not in visited:
                    stack.append(adjacent_node)

# 그래프를 인접 리스트로 표현한 예시
graph = {
    'A': ['B', 'C'],
    'B': ['A', 'D', 'E'],
    'C': ['A', 'F'],
    'D': ['B'],
    'E': ['B', 'F'],
    'F': ['C', 'E']
}

print("깊이 우선 탐색 결과:")
dfs(graph, 'A')

 

 

 

 

BFS 너비탐색 알고리즘 코드구현

 

from collections import deque
#먼저 collections 모듈에서 deque를 가져옵니다. 
#deque는 양쪽 끝에서의 빠른 append와 popleft 연산을 지원하는 큐(queue) 자료구조입니다

#이 함수는 그래프와 시작노드를 인자로 받는다.
def bfs(graph, start):
    visited = set()  # 방문한 노드를 저장하기 위한 집합 초기셋팅
    queue = deque([start])  # 탐색할 노드를 저장하기 위한 큐
    visited.add(start)  # 시작 노드를 방문 처리
    
    #큐가 비어있지 않은 동안 반복한다
    while queue:
        node = queue.popleft()  # 큐에서 가장 앞에 있는 노드를 가져옴. popleft를 해서큐에서 노드를 제거
        print(node, end=' ')
        
        # 인접한 노드들 중에서 방문하지 않은 노드를 큐에 추가하고 방문 처리
        
        for adjacent_node in graph[node]: #현재 처리중인 node의 인접한 노드들을 순회
            if adjacent_node not in visited:#방문했다는 집합에 해당노드가 없다면
                queue.append(adjacent_node) #큐에다가 인접 노드 넣기
                visited.add(adjacent_node) #방문했다고 방문집합에 추가하기

# 그래프를 인접 리스트로 표현한 예시
graph = {
    'A': ['B', 'C'],
    'B': ['A', 'D', 'E'],
    'C': ['A', 'F'],
    'D': ['B'],
    'E': ['B', 'F'],
    'F': ['C', 'E']
}

print("너비 우선 탐색 결과:")
bfs(graph, 'A')

 

코드풀이는 다음과 같다~

 

선택한 시작 노드 주변을 확인. 

(인접노드 확인).

 확인할 애들을 큐에 저장

확인마친, 즉 방문한 애들은 방문집합에 저장.

 

큐가 텅빌때까지 반복

확인할 노드는 큐에서 꺼내서 씀. 맨 처음 넣은 앞에서부터 꺼낼거임

 

그래프의 현재 노드  주변에 있는 애들을  for문 반복문으로 다 확인해볼것임

 방문집합에 해당 노드가 없다면 방문안한거니까

아까 꺼냈던 노드를 큐에다가 다시 추가

그리고 그 노드에 방문(그 노드를 탐색)한거니까  방문집합에 그 노드를 넣는다. 

 

728x90
728x90

while은 조건문이 true일 때 수행하고 

조건이 false가 되면 빠져나온다. (강제로 빠져나오고 싶을 때 break)

 

for문은 순서열 처음부터 끝까지 실행

728x90
728x90

자바스크립트와 달리 === 연산자 없다. 

 

파이썬에서 대입 연산자는 = 기호뿐입니다. 변수에 값을 할당하는 데 사용됩니다.

반면에 ==는 두 값이 같은지 여부를 확인하는 비교 연산자입니다. 값이 같으면 True를 반환하고 그렇지 않으면 False를 반환합니다. 예를 들어, x == y는 x와 y의 값이 같은지 확인합니다.

Python에는 JavaScript와 같은 === 연산자가 없습니다. 대신 is 키워드를 사용하여 두 변수가 메모리에서 동일한 개체를 참조하는지 여부를 확인할 수 있습니다. 예를 들어 x is y는 x와 y가 동일한 개체를 참조하는지 여부를 확인합니다.

 

조건 있을 때 elif

조건없을 때 else

728x90
728x90

https://docs.page/invertase/react-native-google-mobile-ads

 

React Native Google Mobile Ads

 

docs.page

 

ios, android 

react native에서 셋팅하는 법~!

 

1. 설치하기

# Install the admob module
yarn add react-native-google-mobile-ads

2. 

app.json 파일에 추가하기

// <project-root>/app.json
{
  "react-native-google-mobile-ads": {
    "android_app_id": "ca-app-pub-xxxxxxxx~xxxxxxxx",
    "ios_app_id": "ca-app-pub-xxxxxxxx~xxxxxxxx"
  }
}

 

각 앱 id는 애드몹에서 받아와야한다. 

애드몹 계정 생성하기~!

(참고로 애드몹 계정 생성할 때 개인/법인 잘 선택해야함. 계좌 유형에서 개인에서 법인으로 바꾸고 싶었는데 안되어서

삭제하고 다시 만듦...유형 바꿀 수 없다고 해서!!!)

 

3. 애드몹 계정 생성 후 앱 ID 받아서 app.json파일에 넣기

앱추가하기: 앱 > 앱 추가

앱 ID 받아오기 : 앱> 앱 설정 > 앱 ID

4. SKAdNetwork를 활성화하여 전환 추적(iOS)
"Google 모바일 광고 SDK는 IDFA를 사용할 수 없는 경우에도 Google 및 참여하는 제3자 구매자가 앱 설치를 기여할 수 있는 Apple의 SKAdNetwork를 사용하여 전환 추적을 지원합니다. 프로젝트 app.json 파일 내에서 50개의 필수 SKAdNetwork 식별자를 추가합니다."

 

아래처럼 추가

{
  "react-native-google-mobile-ads": {
    "android_app_id": "ca-app-pub-xxxxxxxx~xxxxxxxx",
    "ios_app_id": "ca-app-pub-xxxxxxxx~xxxxxxxx",
    "sk_ad_network_items": [
      "cstr6suwn9.skadnetwork",
      "4fzdc2evr5.skadnetwork",
      "4pfyvq9l8r.skadnetwork",
      "2fnua5tdw4.skadnetwork",
      "ydx93a7ass.skadnetwork",
      "5a6flpkh64.skadnetwork",
      "p78axxw29g.skadnetwork",
      "v72qych5uu.skadnetwork",
      "ludvb6z3bs.skadnetwork",
      "cp8zw746q7.skadnetwork",
      "c6k4g5qg8m.skadnetwork",
      "s39g8k73mm.skadnetwork",
      "3qy4746246.skadnetwork",
      "3sh42y64q3.skadnetwork",
      "f38h382jlk.skadnetwork",
      "hs6bdukanm.skadnetwork",
      "prcb7njmu6.skadnetwork",
      "v4nxqhlyqp.skadnetwork",
      "wzmmz9fp6w.skadnetwork",
      "yclnxrl5pm.skadnetwork",
      "t38b2kh725.skadnetwork",
      "7ug5zh24hu.skadnetwork",
      "9rd848q2bz.skadnetwork",
      "y5ghdn5j9k.skadnetwork",
      "n6fk4nfna4.skadnetwork",
      "v9wttpbfk9.skadnetwork",
      "n38lu8286q.skadnetwork",
      "47vhws6wlr.skadnetwork",
      "kbd757ywx3.skadnetwork",
      "9t245vhmpl.skadnetwork",
      "a2p9lx4jpn.skadnetwork",
      "22mmun2rn5.skadnetwork",
      "4468km3ulz.skadnetwork",
      "2u9pt9hc89.skadnetwork",
      "8s468mfl3y.skadnetwork",
      "av6w8kgt66.skadnetwork",
      "klf5c3l5u5.skadnetwork",
      "ppxm28t8ap.skadnetwork",
      "424m5254lk.skadnetwork",
      "ecpz2srf59.skadnetwork",
      "uw77j35x4d.skadnetwork",
      "mlmmfzh3r3.skadnetwork",
      "578prtvx9j.skadnetwork",
      "4dzt52r2t5.skadnetwork",
      "gta9lk7p23.skadnetwork",
      "e5fvkxwrpn.skadnetwork",
      "8c4e2ghe7u.skadnetwork",
      "zq492l623r.skadnetwork",
      "3rd42ekr43.skadnetwork",
      "3qcr597p9d.skadnetwork"
    ]
  }
}

배너 광고를 쓸 것이기에 

 

5. 애드몹에서 배너광고 생성

앱 > 광고 단위 > 광고 단위 추가

배너 선택해서 추가

추가하면 

광고 단위 ID 가 나옴

 

6. 앱에 배너광고 붙이기

 

 

원하는 화면에 다음과 같이 붙이기

ca-app-pub-xxxxxxxxxxxxx/yyyyyyyyyyyyyy 이 자리에 

광고 단위 ID  넣기

import React from 'react';
import { BannerAd, BannerAdSize, TestIds } from 'react-native-google-mobile-ads';

const adUnitId = __DEV__ ? TestIds.BANNER : 'ca-app-pub-xxxxxxxxxxxxx/yyyyyyyyyyyyyy';

function App() {
  return (
    <BannerAd
      unitId={adUnitId}
      size={BannerAdSize.ANCHORED_ADAPTIVE_BANNER}
      requestOptions={{
        requestNonPersonalizedAdsOnly: true,
      }}
    />
  );
}

--

나는 android , ios 각각 광고단위ID가 있어서 다음과 같이 넣어줌. 

import {Platform } from 'react-native'

const unitId =
  Platform.OS === 'ios'
    ? 'ca-app-pub-....'
    : 'ca-app-pub-....'
    
    
 
 const Home = ()=>{
 return <>  <BannerAd
          // unitId={TestIds.BANNER}
          unitId={unitId}
          size={BannerAdSize.ANCHORED_ADAPTIVE_BANNER}
        />
        </>
 }
 export default Home

 

 

7. 부정클릭 막기 

테스트 기기 등록

앱>설정>기기 테스트

 

 

안드로이드: 설정>Google>광고>이 기기의 광고ID
iOS: idfa 추출가능한 앱 설치(예: TUNE) >IFA(IDFA)

 

이렇게 가져오면 됨. 근데 IOS에서 IFA가 안뜬다?

하면 설정에서 

앱 추적 권한을 허용하면 된다~!~!

 

부정클릭 막는 이유 -

애드몹에서 부정클릭으로 간주하면 앱이 정지될 수 있다고 함!

같은 IP주소도 확인하고 패턴으로 인위적은 클릭을 감지한다고..

 

--

번외)

 

이렇게 보면 간단하지만..

ios빌드는 잘되어도

안드로이드 빌드가 상당히 힘들었다..

 

1. 모듈의 종속성이 중복되어서 일어난 빌드 에러

Duplicate class com.google.android.gms.measurement.internal.zzit found in modules 블라블라

 

 

app/build.gradle 파일에서

 

이런 식으로 해당 라이브러리 쓸 때 중복되는 애들을 제외시키는 exclude를 추가해봤는데도 안되었음

implementation('com.example:my-library:1.0') {
    exclude group: 'com.google.android.gms'
}

내가 쓰고 있는 모듈의 종속성 확인하는 방법 명령어 (./gradlew clean 이거는 캐시 지우는거~)

cd android && ./gradlew clean && ./gradlew app:dependencies

 

1-1. 해결방법

app/build.gradle 파일 하단에 이거 추가함

버전을 고정으로 박아둠. 

해결책을 chatgpt로 찾았다!


configurations.all {
  resolutionStrategy {
    force 'com.google.android.gms:play-services-ads:20.4.0'
    force 'androidx.work:work-runtime:2.7.0'
  }
}

2. react-native-google-mobile-ads 라이브러리 말고 다른 대안?

 

안드로이드 빌드해결 못하고 눈을 돌려 firebase로 애드몹 연동해서 쓸까했지만...

react-native-firebase를 깔고 보니

"Firebase SDK에서 Admob을 더이상 지원하지 않습니다. 따라서 최신 react-native-firebase를 사용하면 Admob을 사용할 수 없습니다."라 해서 다시 원점으로 돌아왔었음.

 

react-native-admob-native-ads 

추가로 찾아본 이 라이브러리는 내가 썼던 애랑 같은 라이브러리라고 함.

 

 

 

 

728x90
728x90

재귀함수

나 자산을 또 호출하는 함수

 

반복적으로 실행함

그래서 재귀 함수 만들 때!

 

1. recurrence relation 점화식

2. base case 

꼭있어야함. 

 

점화식으로 계속 반복되고 

그 반복이 base case에 도달하면 재귀함수가 끝이 남. 

base case가 없으면 무한루프되므로 주의!

 

Tree 개념

 

노드: 트리는 보통 노트로 구현

차수degree 각노드가 갖는 자식의 수

 

모든 노드의 차수가 N개 이하인 트리를 n진 트리라 한다. 

 

Binary Tree 이진트리 

차수가 2진 이하 

이 노드들의 구성 요소:

value값 저장, left child 주소값 저장, right child wnthrkqt wjwkd

 

코드로 구현시:

1. 이렇게 구현된 노드생성 

 

2. binary Tree 구성

 

트리 순회Traversal (= 트리탐색, 완전탐색)

트리의 각 노드를 방문하는 과정을 말함

모든 노드를 한번씩 방문해야해서 순회 방법으로는 

너비우선탐색의 BFS Breadth-First Search

깊이우선탐색의 DFS Depth-First Search

 

 

BFS

root기준으로 탐색. 아래로 level 0, level1 이렇게 가까운것부터 탐색

 

순회해서 그 노드에 "방문한다"

->

그 노드에 접근하는 것은 언제든 할 수 있음.

근데 "방문"은 그노드에 접근해서 "어떤 작동을 시키는 것"

 

트리순회에서 그냥 접근하는 것과 방문하는 것은 다름!

 

 

DFS

스택 반복문으로도 만들 수 있고

재귀로도 만들 수 있음.

 

DFS는 접근 어떻게 할지 생각하고 방문 어떻게 할지 생각.

접근을 재귀로 한다. 

방문은 순회 종류에 따라 다른데

전위순회 preorder

자식노드들에게 가기 전에 일단 자기 자신 방문(기록을 하든 뭘하든..)먼저함.

중위순회 inorder

나 자신을 방문하는게 중간에 있음

후위순회 postorder

자식들 다 방문하고 나서 자기 자신 방문

 

 

 

 

 

 

 

 

 

728x90
728x90

구현 방법 

Array list

Array list + linked list

 

해시테이블은 효율적인 탐색(빠른 탐색)을 위한 자료구조로써 key- value쌍의 데이터를 입력받음

저장,삭제, 검색의 시간복잡도 O(1)

 

키가 걍 Index로 쓰이기도 하고

문자열이 키면 그걸로 index 지정할 수 없어서 

index를 따로 부여하기도 함. 

 

근데 경우에 따라 해시테이블의 collision 충돌 가능성있음. 

 

index를 key로 저장

 

 

 

 

 

728x90
728x90

linked list는 Node라는 구조체가 연결되는 형식으로 데이터를 저장하는 자료구조이다. 

Node는 데이터 값과 next node의 주소값을 저장한다. 

 

linked list는 메모리 상에서는 비연속적 저장되어있지만 

각각의 node가 next node의 메모리 주소값을 가리킴으로써 

논리적은 연속성을 갖게 된다. 

 

 

 

Array list는 연속성 유지하려면 순차적으로 저장해야하지만

linked list는 자유롭다. 

주소값을 함께 저장하기 때문에! 근데 그만큼 데이터당 차지하는 메모리가 더 커지게 된다. 

 

linked list 구현시 

1. head값을 가져야함!!

 

2. head가 linked list의 첫번째 노드값을 가리켜야한다!

이렇게 되면 어느 인덱스에 있는 데이터에도 접근할 수 있다.

 

3. 마지막 노드는 다음 메모리주소가 0(none)이어야한다.

 

 

 

 

linked list의 가장 간단한 연산자 append()

get() 특정 index에 저장되어있는 값을 가져오는 연산자.

 

실제 구현시 

양방향으로 왔다갔다하는 양방향 doubled linked list도 있음

 

 

 

 

 

728x90
728x90

prisma init

 

 

schema.prisma 파일안에 

datasource db {
    provider = "mysql"
    url      = "mysql://유저:비번@localhost:3306/markhouse__"
}

//Prisma Generate는 데이터 모델을 사용하여 Prisma Client를 생성하는 도구입니다. 
//Prisma Client를 사용하면 데이터베이스에 대한 CRUD 작업을 쉽게 수행할 수npx prisma migrate reset 있습니다.

generator client {
    provider = "prisma-client-js"
}

model User {
    id    Int     @id @default(autoincrement())
    email String  @unique
    name  String?
    posts Post[]
}

model Post {
    id       Int    @id @default(autoincrement())
    title    String
    author   User   @relation(fields: [authorId], references: [id])
    authorId Int
}

 

❯ npx prisma db push
Prisma schema loaded from prisma/schema.prisma
Datasource "db": MySQL database "markhouse__" at "localhost:3306"

MySQL database markhouse__ created at localhost:3306

🚀  Your database is now in sync with your Prisma schema. Done in 136ms

✔ Generated Prisma Client (4.10.1 | library) to ./node_modules/@prisma/client in 44ms

 

| markhouse__생김

 

 

 

 

+

만약 show tables를 실행했을 때 _prisma_migrations 테이블만 보인다면, 아마도 Prisma Migrate를 통해 생성한 마이그레이션 파일로 데이터베이스 스키마를 생성하지 않은 것으로 추정됩니다.

Prisma Migrate를 사용하여 데이터베이스 스키마를 생성하려면 다음과 같은 단계를 따라야 합니다.

  1. prisma init 명령어를 사용하여 Prisma 프로젝트를 초기화합니다.
  2. schema.prisma 파일을 생성하고, 데이터베이스 스키마를 정의합니다.
  3. prisma migrate save 명령어를 사용하여 마이그레이션 파일을 생성합니다.
  4. prisma migrate up 명령어를 사용하여 마이그레이션을 적용하여 데이터베이스 스키마를 생성합니다.

위 단계를 수행하고 나면 show tables 명령어를 실행하여 데이터베이스 내 모든 테이블을 볼 수 있습니다. 만약 테이블이 여전히 보이지 않는다면, DBeaver에서 해당 데이터베이스에 대한 연결을 확인해야 합니다. 데이터베이스 연결이 올바른지 확인하고, 다시 시도해 보시기 바랍니다.

 

 

권한 문제가 생긴다면

 

모든 사용자 조회하는 법 

SELECT user, host FROM mysql.user;

 

사용자 조회해보고

비밀번호 확인해볼 것(모른다면 재설정하기)

ALTER USER '사용자명'@'호스트명' IDENTIFIED BY '새로운 비밀번호';

또는

ALTER USER '사용자명'@'호스트명' IDENTIFIED WITH mysql_native_password BY 'new_password';

 

권한도 확인해볼 것

권한 체크 

SHOW GRANTS FOR 'database_user'@'localhost';

권한 주기

GRANT CREATE, DROP ON *.* TO 'database_user'@'localhost';

 

 

root 모든 걸 볼수 있는거 

다른 권한에서 만든 것도 볼 수 있음 

 

다른 유저로 안들어가졌던 이유는 그저 비번 틀려서 접근 안되었던 거였음. 

 

dbeaver는 그냥 mysql에서 만든 데이터 깔끔하게 보여주는 툴임. 

localhost, 유저, 비번 잘입력하면 연결은 되어서 생성됨

 

추가로 테이블 생성했을 때 mysql터미널에서는 생긴게 보이는데 dbeaver에 바로 반영안되는 이유가 뭐지?

아 dbeaver refresh 버튼 눌러서 새로고침하니까 있다 얏호~!~!~!~

 

 

 

+

 

root는 MySQL에서 가장 높은 권한을 가진 사용자입니다. root 사용자는 모든 데이터베이스와 모든 객체에 대한 모든 권한을 가지고 있습니다. 즉, root 사용자는 MySQL 서버에서 모든 작업을 수행할 수 있습니다.

MySQL에서 root 사용자는 기본적으로 "localhost" 호스트에서만 로그인할 수 있습니다. 이는 보안상의 이유로 설정되어 있습니다. 따라서, 원격 호스트에서 root 계정으로 로그인하려면 특별한 설정이 필요합니다.

그러나, root 계정은 매우 강력하며 위험하기 때문에 일반적으로 MySQL 서버에는 다른 사용자 계정을 만들어 사용합니다. 이렇게 하면 보안상의 문제를 최소화할 수 있습니다.

 

+

 

sudo는 "Superuser Do"의 준말로, 리눅스나 유닉스 시스템에서 일반 사용자가 시스템 관리자(root)의 권한을 일시적으로 얻을 수 있는 명령어입니다.

리눅스나 유닉스 시스템에서 root 계정은 시스템 전체를 관리할 수 있는 권한을 가지고 있으므로, root 권한을 가진 사용자로 로그인하면 시스템 보안에 큰 위험이 따릅니다. 따라서, 보안상의 이유로 일반 사용자가 root 권한을 가지지 못하도록 설정되어 있습니다.

이때, 일반 사용자가 시스템 관리 작업을 수행해야 할 경우, sudo 명령어를 사용하여 일시적으로 root 권한을 얻을 수 있습니다. 이때, 사용자는 자신이 수행하려는 작업을 sudo 명령어 뒤에 입력하면 됩니다.

예를 들어, 일반 사용자가 시스템 업데이트를 수행하려면 다음과 같이 sudo 명령어를 사용할 수 있습니다.

 

+

mysql_native_password는 MySQL에서 기본으로 제공하는 인증 플러그인 중 하나입니다.

이 플러그인은 기존의 비밀번호 인증 방식과 호환되도록 설계되어 있어, 기존에 비밀번호로 인증했던 사용자들도 계속해서 이 플러그인을 사용하여 인증할 수 있습니다.

auth_socket 플러그인과 달리, mysql_native_password 플러그인을 사용하는 경우에는 비밀번호가 필요합니다. 따라서, 해당 사용자의 비밀번호를 잊어버린 경우에는 비밀번호를 재설정해주어야 합니다.

만약 mysql_native_password 플러그인 대신 caching_sha2_password 플러그인을 사용하는 경우에는, 새로운 비밀번호를 설정할 때 IDENTIFIED WITH mysql_native_password 구문을 생략해야 합니다.

 

728x90
728x90

Docker는 개발자가 격리된 컨테이너 내에서 애플리케이션을 생성, 배포 및 실행할 수 있도록 하는 인기 있는 오픈 소스 컨테이너화 플랫폼입니다. 컨테이너는 모든 종속성 및 구성 파일과 함께 애플리케이션을 다양한 컴퓨팅 환경에서 일관되게 실행할 수 있는 단일 단위로 캡슐화하는 경량의 독립 실행형 휴대용 패키지입니다.

Docker는 애플리케이션과 해당 종속성을 컨테이너 이미지로 패키징하는 방법을 제공합니다. 그런 다음 기본 운영 체제나 하드웨어 아키텍처에 관계없이 Docker가 설치된 모든 머신에서 배포 및 실행할 수 있습니다. 이렇게 하면 호환성 문제의 가능성이 줄어들고 필요한 인프라를 설정하는 데 필요한 시간과 노력이 최소화되므로 애플리케이션을 더 쉽게 개발, 테스트 및 배포할 수 있습니다.

Docker는 소프트웨어 개발 업계, 특히 클라우드 컴퓨팅 및 DevOps 환경에서 널리 사용되며 마이크로서비스, 서버리스 아키텍처 및 기타 최신 클라우드 네이티브 애플리케이션을 구축하고 배포하는 데 필수적인 도구가 되었습니다.

 

 

Docker 컨테이너 vs Docker 이미지 

 

Docker 컨테이너는 Docker 이미지의 런타임 인스턴스입니다. 즉, 컨테이너는 이미지에서 생성되고 코드, 런타임, 시스템 도구, 라이브러리 및 설정을 포함하여 특정 애플리케이션을 실행하는 데 필요한 모든 것을 포함하는 가볍고 격리된 환경입니다.

컨테이너는 Docker가 호스트 시스템에 설치되어 있는 한 변경 없이 여러 환경에서 실행될 수 있는 이식 가능하고 일관된 단위로 애플리케이션과 해당 종속성을 패키징하는 방법을 제공합니다. 각 컨테이너는 자체 파일 시스템, 네트워킹 및 리소스와 함께 자체 격리된 공간에서 실행되며 동일한 호스트의 다른 컨테이너와 독립적으로 시작, 중지 및 제거될 수 있습니다.

 

반면 Docker 이미지는 컨테이너를 만드는 데 필요한 모든 지침과 종속성을 포함하는 정적 읽기 전용 청사진 또는 템플릿입니다. 이미지는 기본 이미지 또는 기타 기존 이미지에서 이미지를 빌드하는 데 필요한 단계와 명령을 정의하는 텍스트 파일인 Dockerfile을 실행하여 생성됩니다.

요약하면 Docker 컨테이너와 Docker 이미지의 주요 차이점은 컨테이너는 이미지의 런타임 인스턴스인 반면 이미지는 컨테이너를 만드는 데 사용되는 정적 사전 구성된 패키지라는 것입니다. 이미지는 컨테이너를 빌드하는 데 사용되고 컨테이너는 애플리케이션을 실행하는 데 사용됩니다.

 

Docker 이미지가 진짜 그 이미지인가?

 

아니요, Docker 이미지는 그림이나 사진이라는 의미에서 실제 이미지가 아닙니다. 대신 Docker 이미지는 특정 애플리케이션 또는 서비스를 실행하는 데 필요한 모든 필수 파일, 라이브러리 및 종속성을 포함하는 사전 구성된 휴대용 패키지입니다.

Docker에서 "이미지"라는 용어를 사용하는 이유는 개체 또는 장면의 사진을 찍는 것과 유사하게 애플리케이션의 특정 상태 또는 구성에 대한 스냅샷 또는 표현을 생성한다는 아이디어를 반영하기 때문입니다. Docker 이미지는 코드, 런타임 및 구성 설정을 포함하여 애플리케이션의 현재 상태를 캡처하고 모든 Docker 지원 환경에서 공유, 배포 및 실행할 수 있는 자체 포함 단위로 패키징합니다.

 

 

 

 

728x90
728x90

Prisma와 Nexus는 모두 GraphQL 개발을 보다 쉽고 간편하게 할 수 있도록 도와주는 도구입니다.

그러나 두 도구는 서로 다른 목적과 기능을 가지고 있으며, 서로 다른 역할을 합니다.

 

Prisma는 데이터베이스 ORM(Object-Relational Mapping)으로, 데이터 모델과 데이터베이스 스키마를 정의하고 데이터베이스에 접근할 수 있는 API를 제공합니다. Prisma는 데이터베이스 스키마를 정의하기 위해 prisma/schema.prisma 파일을 사용하며, 이를 통해 데이터 모델을 작성하고 데이터베이스를 마이그레이션하는 작업을 할 수 있습니다.

 

반면에 Nexus는 GraphQL 스키마를 코드 기반으로 작성하고 구성하는 도구입니다.

Nexus는 GraphQL API를 작성하기 위해 사용되며, Prisma에서 생성된 데이터베이스 API를 사용하거나 다른 데이터 소스로부터 데이터를 가져와 GraphQL API를 구성할 수 있습니다.

 

따라서 Prisma와 Nexus는 각각의 목적과 기능을 가지고 있으며, 같이 사용할 수 있습니다. Prisma는 데이터베이스 ORM으로서 데이터베이스에 대한 접근을 쉽게 하고, Nexus는 GraphQL API를 작성하기 위한 도구로서 Prisma와 함께 사용하여 간편하게 GraphQL API를 구성할 수 있습니다. Prisma와 Nexus를 같이 사용하면 보다 쉽고 간편하게 GraphQL API를 구성할 수 있습니다.

728x90
728x90

nodejs 는 

chrome v8 javascrpit엔진으로 빌드된 javascript런타임이다.

 

( "자바스크립트 런타임"이란 "자바스크립트 코드를 실행하는 환경"을 말한다. 

자바스크립트는 일반적으로 브라우저에서 실행된다. 

다른 환경에서도 실행될 수 있지만 이를 위해서는 자바스크립트 엔진을 다른 프로그램에 내장하여 자바스크립트 코드를 실행할 수 있는 환경을 만들어야한다. 자바스크립트 엔진과 함께 필요한 라이브러리, 모듈, api 등을 포함하는 것이 자바스크립트 런타임이다. 

)

 

브라우저에서 실행되는 자바스크립트와 달리 nodejs 는 파일 시스템,네트워크 등과 같은

서버 사이드 기능을 제공하여, 서버 사이드 웹 개발을 위한 환경을 제공한다. 

이를 통해 *비동기식 I/O, 이벤트 기반 처리 모델 등을 활용해 높은 성능의 웹 애플리케이션을 만들 수 있다.

 

또한 노드js는 npm이라는 패키지 매니저를 제공한다. node package manager

이를 통해 라이브러리, 모듀르 프레임워크 등의 다양한 패키지를 쉽게 설치하고 관리할 수 있다.

 

 

(I/O(Input/Output)는 컴퓨터에서 데이터를 읽고 쓰는 작업을 말합니다. 이때, 데이터를 읽고 쓰는 과정에서 CPU는 다른 작업을 수행할 수 없는 차단(blocking) 상태에 빠지게 됩니다. 이러한 문제를 해결하기 위해 비동기식 I/O(Asynchronous I/O)가 등장했습니다.)

 

+

express는 

노드Js를 위한 웹 프레임워크이다. 간결하고 유연한 구조를 가지고 있는 것이 특징

노드js의 http 모듈을 기반으로하며, 

http 요청

라우팅 및 미들웨어 처리를 쉽게 할 수 있도록 한다.

 

다음과 같은 기능을 제공한다. 

  1. 라우팅: HTTP 요청의 URL을 해당하는 처리기(콜백 함수)에 매핑합니다. 이를 통해 사용자는 특정 URL에 대한 요청에 대한 적절한 응답을 반환할 수 있습니다.
  2. 미들웨어: 요청을 처리하기 전에 실행되는 작업을 구성할 수 있습니다. 예를 들어 요청 헤더의 유효성을 검사하거나 로깅을 수행하는 등의 작업을 수행할 수 있습니다. 또한 미들웨어를 사용하여 사용자 정의 라우팅 및 오류 처리 논리를 구현할 수도 있습니다.
  3. HTTP 요청 및 응답: Express는 HTTP 요청 및 응답을 쉽게 처리할 수 있는 기능을 제공합니다. 예를 들어 요청 본문을 구문 분석하거나 특정 상태 코드로 응답을 반환할 수 있습니다.
  4. 뷰 엔진: Express는 다양한 뷰 엔진을 지원합니다. 이를 통해 사용자는 HTML 및 CSS와 같은 마크업 언어로 페이지를 렌더링할 수 있습니다. 대표적인 뷰 엔진으로는 Pug, EJS, Handlebars 등이 있습니다.

 

728x90
728x90

GraphQL은 Facebook에서 개발하고 오픈 소스로 제공하는 API(애플리케이션 프로그래밍 인터페이스)용 쿼리 언어 및 런타임입니다. API 구축을 위해 REST(Representational State Transfer)에 대한 보다 효율적이고 강력하며 유연한 대안을 제공합니다.

GraphQL API에서 클라이언트는 필요한 데이터를 지정하는 요청을 하고 서버는 고정된 데이터 집합이 아닌 요청된 데이터만 반환합니다. 이렇게 하면 데이터를 과도하게 가져오거나 적게 가져오지 않고 필요한 데이터를 정확하게 검색하고 여러 요청이 아닌 단일 요청으로 데이터를 받을 수 있습니다.

GraphQL은 또한 클라이언트와 서버 간에 교환되는 데이터에 대한 유형 시스템을 제공하여 요청과 응답이 실행되기 전에 유효성을 검사할 수 있도록 합니다. 그 결과 성능이 향상되고 복잡성이 감소하며 API가 더 예측 가능해집니다.

GraphQL의 또 다른 주요 기능은 실시간 업데이트 및 구독 지원으로, 실시간 및 협업 애플리케이션 구축에 매우 적합합니다.

전반적으로 GraphQL은 API를 구축하는 보다 효율적이고 유연하며 강력한 방법을 제공하며 특히 여러 데이터 소스 및 서비스와 상호 작용해야 하는 모바일 및 웹 애플리케이션을 위한 최신 애플리케이션 개발에 널리 사용되는 선택이 되었습니다.

GraphQL is a query language and runtime for APIs (Application Programming Interfaces) that was developed and open-sourced by Facebook. It provides a more efficient, powerful, and flexible alternative to REST (Representational State Transfer) for building APIs.

In a GraphQL API, the client makes a request specifying the data it needs, and the server returns only the requested data, rather than a fixed set of data. This makes it possible to retrieve exactly the data you need, without over- or under-fetching data, and to receive the data in a single request, rather than multiple requests.

GraphQL also provides a type system for the data being exchanged between the client and the server, making it possible to validate the requests and responses before they are executed. This results in better performance, reduced complexity, and a more predictable API.

Another key feature of GraphQL is its support for real-time updates and subscriptions, which makes it well-suited for building real-time and collaborative applications.

Overall, GraphQL provides a more efficient, flexible, and powerful way to build APIs, and has become a popular choice for developing modern applications, especially for mobile and web applications that need to interact with multiple data sources and services.

728x90

'데이터베이스' 카테고리의 다른 글

러닝MySQL 2장 데이터베이스 모델링과 설계  (0) 2024.02.18
몽고디비 공부중..  (0) 2021.11.10
728x90

The error message ERROR 1044 (42000): Access denied for user 'root'@'localhost' to database '' in MySQL indicates that the user root@localhost doesn't have sufficient privileges to access the database specified in the command.

Here are the steps to resolve the issue:

  1. Connect to the MySQL server with an administrative account:
 
`mysql -u root -p`
  1. Grant the required privileges to the user:
 
`GRANT ALL PRIVILEGES ON database_name.* TO 'root'@'localhost';`

Replace database_name with the name of the database you want to grant privileges to. The ALL PRIVILEGES clause grants all privileges to the user, including the ability to create, modify, and delete data in the database.

  1. Flush the privileges to make the changes take effect:
Copy code
FLUSH PRIVILEGES;
  1. Try accessing the database again and see if the error still occurs.

This should resolve the issue and allow the user root@localhost to access the specified database.

 

728x90
728x90

In the context of relational databases, the terms "database" and "schema" are often used interchangeably, but they have different meanings.

A database is a collection of related data stored in a specific and organized way, allowing for easy retrieval and management of the data. A database can contain multiple tables, views, and other database objects.

A schema is a logical container for organizing database objects, such as tables, views, indexes, procedures, and functions, within a database. A schema provides a way to organize the database objects in a logical and meaningful manner.

In other words, a schema can be thought of as a blueprint or blueprint plan of how the database is structured and how the data is organized within it. A database can contain multiple schemas, and each schema can contain multiple tables and other objects.

In short, a database is a physical container for storing data, while a schema is a logical container for organizing the database objects within that data.

728x90
728x90

To add a new user in MySQL, you can use the CREATE USER statement followed by the GRANT statement.

Here's an example of how to create a new user named "newuser" with the password "newpassword":

 
CREATE USER 'newuser'@'localhost' IDENTIFIED BY 'newpassword';

Once the user is created, you can grant them privileges using the GRANT statement. For example, to grant the SELECT, INSERT, and UPDATE privileges on a database named "testdb" to the new user, you can use the following command:

 
GRANT SELECT, INSERT, UPDATE ON testdb.* TO 'newuser'@'localhost';

Regarding the "root" user, it is the default administrative user in MySQL. The root user is created during the installation of MySQL and has the highest level of privileges, allowing it to perform any operation on the MySQL server, including creating and modifying users, granting and revoking privileges, and managing databases. The root user is usually created with a password, and you can log in to the MySQL server as the root user by specifying the username and password in the mysql client.

 

728x90

+ Recent posts