CIDR

Understanding CIDR Notation and IP Address Range | by Michel Burnett | Medium

 

Understanding CIDR Notation and IP Address Range

This article will help you become familiar with IP addresses and CIDR notation.

michelburnett27.medium.com

 

라우팅 효율성을 향상시키는 ip주소 할당 방법이다. 

클래스 기반 주소는 a클래스, b클래스, c클래스 이런 식으로 나누는데, 클래스 없는 주소가 CIDR이다. 

가변길이 서브넷마스킹을 사용해서 IP주소의 네트워크와 호스트 주소 간의 비율을 변경한다. 

 

장점: ip주소를 아껴쓸 수 있다. 데이터를 빠르게 전송할 수 있다. 등 이것저것..

단점은 ip주소 지원이 유연하지 않다는 것 그리고 서로 다른 클래스 네트워크에 속하는 두 네트워크르 결합할 수 없다. 

 

'WEB' 카테고리의 다른 글

캐싱, 데이터 재검증, 코드 스플리팅  (0) 2024.08.20
content delivery network, CDN  (0) 2024.08.17
payload, ICMP, Babel  (0) 2024.08.13
CORS, CICD  (0) 2024.08.12
jwt란 무엇인가  (0) 2024.07.15

 

-캐싱

static caching

사용자의 요청이 없어도, 원본 서버의 내용을 미리 캐시 서버에 복사한다. 사용자가 데이터를 요청하면 무조건 캐시 서버에 그 내용이 있다. 캐시 힛이 100퍼센트이다. 

 

dynamic caching

사용자가 캐시 서버에 콘텐츠를 요청하면 해당 서버에 그 콘텐츠가 있는지 확인하고, 없으면(cache miss) 원본 서버로부터 다운 받아서 사용자에게 전달해준다. 그러다가 일정 기간이 지나면 또 그 콘텐츠는 캐시 서버에서 삭제될 수 있다. (암튼 동적임)





-data revalidation(데이터 재검증)

데이터 캐시를 비우고, 최신 데이터를 다시 가져오는 과정이다. 

 

재검증 방법은 시간 기반 재검증, 온디맨드 재검증이 있다. 

 

시간 기반: 리소스의 캐시 수명을 초 단위로 설정해 놓고 재검증을 수행한다. 정적으로 렌더링된 라우트에서 여러 fetch요청이 있고, 재검증 주기가 모두 다르다면 

가장 빨리 재검증되는 시간이 모든 요청에 사용된다. 동적으로 렌더링된 라우트에서는 각각의 fetch 요청을 동적으로 재검증한다. 

 

온디맨드: 

특정 이벤트가 발생할 때(예: 폼 제출 후) 데이터를 수동으로 즉시 업데이트한다. 태그기반 접근 방식과 경로 기반 접근 방식이 있음. 




- 코드 스플리팅

코드분할은 코드를 번들된 코드 혹은 컴포넌트로 분리하는 것입니다. 이렇게하면 필요에 따라 특정한 컴포넌트만 로딩하거나, 병렬로 로딩할 수 있다. 그리고 서버 컴포넌트를 활용하면 코드 분할(split)이 자동으로 된다. 

 

'WEB' 카테고리의 다른 글

CIDR  (0) 2024.08.22
content delivery network, CDN  (0) 2024.08.17
payload, ICMP, Babel  (0) 2024.08.13
CORS, CICD  (0) 2024.08.12
jwt란 무엇인가  (0) 2024.07.15

-CDN

content delivery network의 약자로.. 

물리적으로 멀리 떨어져 있는 사용자에게 컨텐츠를 더 빠르게 제공하는 기술. 

 

서버를 분산시킨 후 각 서버에 데이터를 캐싱해두고, 사용자의 컨텐츠 요청이 들어오면 사용자와 가장 가까운 위치의 서버에서 캐싱된 데이터를 사용자에게 전달한다. 만약 가장 가까운 서버에 없다면 CDN 플랫폼에 있는 다른 서버에게 요청하는.. 그런 네트워크이다.



 

 

'WEB' 카테고리의 다른 글

CIDR  (0) 2024.08.22
캐싱, 데이터 재검증, 코드 스플리팅  (0) 2024.08.20
payload, ICMP, Babel  (0) 2024.08.13
CORS, CICD  (0) 2024.08.12
jwt란 무엇인가  (0) 2024.07.15

-payload

전송되는 데이터들 중 메타데이터 같은 거 제외하고, 바디 부분 안에 있는 데이터. 전송 목적이 되는 그 데이터 자체를 페이로드라고 한다. 지급해야 하는 것은 차체, 운전자 무게 같은 거 다 빼고, 적재된 기름의 무게뿐이다. 그래서 지급해야하는 적화물 = 페이로드, 흥미 있는 데이터가 된 것. 




-ICMP

 인터넷 제어 메시지 프로토콜



-Babel

자바스크립트 코드를 변환해주는 도구(javascript 컴파일러)

ES6문법들을 예정 버전의 문법으로 변환할 수 있게 해줌→ 크로스브라우징할 때 자바스크립트 호환성 문제를 해결할 수 있다.

parsing, transforming, printing

 

'WEB' 카테고리의 다른 글

CIDR  (0) 2024.08.22
캐싱, 데이터 재검증, 코드 스플리팅  (0) 2024.08.20
content delivery network, CDN  (0) 2024.08.17
CORS, CICD  (0) 2024.08.12
jwt란 무엇인가  (0) 2024.07.15

 

 

 

CORS란?

Cross-Origin Resource Sharing 

 

웹 브라우저가 서로 다른 도메인, 프로토콜, 또는 포트에서 리소스를 요청할 때 적용되는 보안 정책이다. 웹 브라우저는 보안상의 이유로, 기본적으로 동일 출처 정책(Same-Origin Policy)을 따른다. 

한 출처에서 로드된 웹 페이지는 다른 출처에서 로드된 리소스에 접근할 수 없다. 

 

동일 출처 정책은 Cross-Site Scripting 공격과 같은 보안 문제를 방지하는 데 중요한 역할.

 

 

 

 

CI/CD란?



Continuous Integration, Continuous Delivery의 약자이다. 

 

지속적인 통합, 지속적인 델리버리를 해주는 파이프라인이다.

개발 단계부터 테스트, 스테이징을 거쳐 최종적으로 출시하기 위해 코드가 거치는 일정한 단계. 

 

'WEB' 카테고리의 다른 글

CIDR  (0) 2024.08.22
캐싱, 데이터 재검증, 코드 스플리팅  (0) 2024.08.20
content delivery network, CDN  (0) 2024.08.17
payload, ICMP, Babel  (0) 2024.08.13
jwt란 무엇인가  (0) 2024.07.15

https://react.dev/learn/reusing-logic-with-custom-hooks 

 

Reusing Logic with Custom Hooks – React

The library for web and native user interfaces

react.dev

여기 공부한 내용

 

 

// import { useState, useEffect } from 'react';


// export default function StatusBar() {
//     const [isOnline, setIsOnline] = useState(true);
//     useEffect(() => {
//         function handleOnline() {
//             setIsOnline(true);
//         }


//         function handleOffline() {
//             setIsOnline(false);
//         }


//         window.addEventListener('online', handleOnline);
//         window.addEventListener('offline', handleOffline);


//         return () => {
//             window.removeEventListener('online', handleOnline);
//             window.removeEventListener('offline', handleOffline);
//         };


       
//     }, []); //처음 마운트될 때만 실행되는 UseEffect 함수.


//     return <h1>{isOnline ? 'online' : 'Disconnected' }</h1>;
// }






// import { useState, useEffect } from 'react';


// export default function SaveButton() {
//     const [isOnline, setIsOnline] = useState(true);
//     useEffect(() =>  {
//         function handleOnline() {
//             setIsOnline(true);
//         }


//         function handleOffline() {
//             setIsOnline(false);
//         }
      
//         window.addEventListener('online',  handleOnline);
//         window.addEventListener('offline', handleOffline);


//         return () => {
//             window.removeEventListener('online', handleOnline);
//             window.removeEventListener('offline', handleOffline);
//         };
//     }, []);


//     function handleSaveClick() {
//         console.log('Progress Saved');
//     }


//     return (
//         <button disabled = {!isOnline} onClick= {handleSaveClick}>
//             {isOnline ? 'Save progress' : 'Reconnecting...'}
//         </button>
//     );
// }






// import { useOnlineStatus } from './useOnlineStatus.js'
// function StatusBar() {
//     const isOnline = useOnlineStatus();
//     return <h1>{isOnline ? 'online' : 'disconnected'}</h1>;
// }


// function SaveButton() {
//     const isOnline = useOnlineStatus();


//     function handleSaveClick() {
//         console.log('progress saved');
//     }


//     return (
//         <button disabled= {!isOnline} onClick={handleSaveClick}>
//             {isOnline ? 'save progress' : 'Reconnecting...'}
//         </button>
//     );
// }










// export default function useOnlineStatus() {
//     const [isOnline, setIsOnline] = useState(true);
//     useEffect(() => {
//       function handleOnline() {
//         setIsOnline(true);
//       }
//       function handleOffline() {
//         setIsOnline(false);
//       }
//       window.addEventListener('online', handleOnline);
//       window.addEventListener('offline', handleOffline);
//       return () => {
//         window.removeEventListener('online', handleOnline);
//         window.removeEventListener('offline', handleOffline);
//       };
//     }, []);
//     return isOnline;
//   }












import {useState} from 'react';


export default function Form() {
   const [firstName, setFirstName] = useState('Mary');
   const [lastName, setLastName] = useState('Poppins');


   function handleFirstNameChange(e) {
       setFirstName(e.target.value);
   }


   function handleLastNameChange(e) {
       setLastName(e.target.value);
   }


   return  (
       <>
           <label>
               First name:
               <input value={firstName} onchange={handleFirstNameChange} />
           </label>
           <label>
               Last Name:
               <input value={lastName} onChange={handleLastNameChange} />
           </label>
           <p><b>Good morning, {firstName} {lastName}.</b></p>
       </>
   );
}


import {useFormInput} from './useFormInput.ts'
export default function Form() {
   const firstNameProps = useFormInput('Shilpa');
   const lastNameProps = useFormInput('Sudir');


   return  (
       <>
           <label>
               First name:
               <input {...firstNameProps} />
           </label>
           <label>
               Last Name:
               <input {...lastNameProps} />
           </label>
           <p><b>Good morning, {firstNameProps.value} {lastNameProps.value}.</b></p>
       </>
   );


}




// import { useFirstName } from './useFirstName.js'




// import {useState, useEffect} from 'react';
// export default function useFirstName() {
//     const [firstName, setFirstName] = useState('Shilpa');


//     useEffect(() => {
//         function handleFirstNameChange(e) {
//             setFirstName(e.target.value);
//         }
//     })
// }


export function useFormInput(initialValue) {
   const [value, setValue] = useState(initialValue);


   function handleChange(e) {
       setValue(e.target.value);
   }


   const inputProps = {
       value: value,
       onChange: handleChange
   };


   return inputProps;
}
















import {useState, useEffect} from 'react' ;
import ChatRoom from './ChatRoom.js';


export default function App() {}








/*
Notice how you no longer nedd to know how "useChatRoom" works in order to use it.
*/


//when to use custom Hooks?




function ShippingForm({ country }){
   const [cities, setCities] = useState(null);


   useEffect(() => {
       let ignore = false;
       fetch(`/api/cities?country=${country}`)
           .then(response => response.json())
           .then(json => {
               if (!ignore) {
                   setCities(json);
               }
           });
       return () => {
           ignore = true;
       };
   }, [country]);




   const [city, setCity] = useState(null);
   const [area, setArea] = useState(null);


   useEffect(() => {
       if (city) {
           let ignore = false;
           fetch(`/api/areas?city=${city}`)
               .then(response => response.json())
               .then(json => {
                   if (!ignore){
                       setArea(json);
                   }
               });
           return () => {
               ignore = true;
           };
       }
   }, [city]);
}






function useData(url) {
   const [data, setData] = useState(null);
   useEffect(() => {
       if (url) {
           let ignore = false;
           fetch(url)
               .then(response => response.json())
               .then(json => {
                   if (!ignore) {
                       setData(json);
                   }
               });
           return () => {
               ignore = true;
           };
       }
   }, [url]);
   return data;
}

크로스 오리진(Cross-Origin)이란 한 웹페이지에서 다른 도메인(주소)의 리소스(데이터, 이미지, 스크립트 등)를 요청하는 것을 말한다. 예를 들어, 네이버 페이지에서 구글 서버의 데이터를 요청하는 경우를 생각하면 된다. 서로 다른 도메인 간의 요청이기 때문에 "크로스 오리진"이라고 부른다.

문제는, 보안상의 이유로 브라우저가 이런 크로스 오리진 요청을 기본적으로 막는다는 점이다. 해커가 악용할 수 있기 때문이다. 그래서 필요할 때만 허용하기 위해 나온 것이 바로 CORS이다.

CORS(Cross-Origin Resource Sharing)는 다른 도메인의 리소스를 요청할 때, 그 요청을 허용할지 말지 서버에서 결정하는 방법이다. 서버는 특정 헤더(HTTP 헤더)를 사용하여 어떤 도메인에서의 요청을 허용할지 브라우저에 알려준다.

예를 들어, 어떤 서버가 모든 도메인의 요청을 허용하려면 다음과 같은 헤더를 응답에 추가한다.

http
코드 복사
Access-Control-Allow-Origin: *

이렇게 하면 모든 도메인의 요청을 받을 수 있다. 특정 도메인만 허용하려면 * 대신 해당 도메인의 주소를 적는다.

요약하자면:

  • 크로스 오리진: 한 도메인에서 다른 도메인의 리소스를 요청하는 것.
  • CORS: 서버에서 크로스 오리진 요청을 허용할지 결정하는 방법.

이렇게 하면 웹 보안이 유지되면서도 필요한 경우 크로스 오리진 요청을 할 수 있다.

자바스크립트 라이브러리 lodash

 

데이터 구조를 쉽게 다룰 수 있게 도와주는 도구이다.

array, collection, date 같은 것들을 쉽게 처리할 수 있다.

특히 js에서 배열 안의 객체 값을 다룰 때 유용하다.

 

 

1. lodash의 .isEmpty() 메서드

 

이 메서드는 오브젝트, 컬렉션, 맵, 세트 등이 비어 있는지 아닌지를 체크하는 도구이다.

비어 있으면 true를 리턴하고, 안 비어 있으면 false를 리턴한다.

 

예를 들어, 빈 배열이나 빈 오브젝트를 .isEmpty()로 체크하면 true를 리턴한다.

반대로, 요소가 하나라도 들어 있는 배열이나 프로퍼티가 있는 오브젝트는 false를 리턴한다.

 
console.log(_.isEmpty([])); // true
console.log(_.isEmpty({})); // true
console.log(_.isEmpty([1, 2, 3])); // false
console.log(_.isEmpty({ 'a': 1 })); // false
 

뿐만 아니라, null이나 undefined 같은 값도 체크할 수 있다. 비어 있는 값으로 간주되므로 (비어있냐? 는 함수니까)true를 리턴한다.

console.log(_.isEmpty(null)); // true
console.log(_.isEmpty(undefined)); // true

 

 

lodash의 .isEmpty() 메서드 쓰면 좋은점:

1. 코드의 가독성이 높아진다.

2. 다양한 데이터 구조를 쉽게 검사할 수 있다. 특히 데이터가 비어 있는지 아닌지 빠르게 확인하고 싶을 때 아주 유용한 도구이다

 

 

 

 

2. lodas의 get 함수

 

get 함수는 객체 안의 깊숙한 속성에 안전하게 접근할 수 있도록 도와주는 유용한 도구이다.

보통 자바스크립트 객체의 깊은 속성에 접근할 때, 해당 속성이 존재하지 않으면 에러가 발생할 수 있다. get 함수를 사용하면 이러한 문제를 피할 수 있다.

예를 들어, 다음과 같은 객체가 있다고 하자:

const user = {
  name: 'John',
  address: {
    city: 'New York',
    zip: {
      code: 10001
    }
  }
};​

이 객체에서 zip 코드에 접근하는 방법은

const zipCode = user.address.zip.code;
원래 이렇다. 

하지만 만약 경로 중간에 있는 address나 zip 속성이 없다면 에러가 발생할 것이다.

get 함수를 사용하면 address나 zip 속성이 없어도 에러가 발생하지 않고 undefined를 반환한다.

 
import { get } from 'lodash'; const zipCode = get(user, 'address.zip.code');

 

 

 

 

 

또한, 아래와 같이 기본값을 설정할 수도 있다.

const zipCode = get(user, 'address.zip.code', 'Unknown');​

이렇게 하면 address나 zip 속성이 없을 때 'Unknown'을 반환한다.

 

 

=lodash의 get 함수를 사용하면 에러를 방지하고 기본값을 설정할 수 있어서 코드가 더 안정적이고 읽기 쉬워진다.

'WEB > Javascript' 카테고리의 다른 글

clsx란?  (0) 2024.07.13
Typescript의 interface  (0) 2024.07.10
enum in typescript  (0) 2024.07.05
타입스크립트에서 타입 지정하는 법  (0) 2024.07.01
[JS] promise~  (0) 2024.05.27

https://school.programmers.co.kr/learn/courses/30/lessons/159994

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

<1차 실패>

def solution(cards1, cards2, goal):
    for i in goal:
        if i == cards1[0]:
            del cards1[0]
        elif i == cards2[0]:
            del cards2[0]
        else: return "No"
    return "Yes"

 

IndexError: list index out of range

 

 

 

 

<2차 성공>

def solution(cards1, cards2, goal):
    for i in goal:
        if cards1 and i == cards1[0]:
            del cards1[0]
        elif cards2 and i == cards2[0]:
            del cards2[0]
        else: return "No"
    return "Yes"

 

인덱스가 레인지를 넘어갈 수도 있다는 오류를 해결하기 위해서 각 조건문에 cards1과 cards2가 1개 이상의 요소를 가지고 있는가? 

라는 부분을 추가하였다. 

https://school.programmers.co.kr/learn/courses/30/lessons/42626

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

#스코빌지수가 가장 낮은 거 + 두 번째로 낮은 거*2 합치기. 모든 음식의 스코빌지수가 k가 넘을 때까지


heapq 쓰면 좋은 점:

더해서 나온 값이 정렬된 리스트에서 제자리를 찾아서 들어가야 계속해서 스코빌지수가 제일 낮은 음식을 heappop으로 구할 수 있다.

import heapq

def solution(scoville, k):
    heapq.heapify(scoville)
    count=0
    while scoville[0]<k:
        if len(scoville)==1:
            return -1
        a=heapq.heappop(scoville)
        b=heapq.heappop(scoville)
        heapq.heappush(scoville, a+(b*2))
        count+=1
    return count

+ Recent posts