Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5,6주차/지나] 워크북 제출합니다. #58

Merged
merged 2 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
198 changes: 198 additions & 0 deletions keyword/chapter05/keyword.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
- 환경 변수
- 정의 : 프로세스가 컴퓨터에서 동작하는 방식에 영향을 미치는, 동적인 값들의 모임
- 필요 이유
- 프로세스가 어떤 작업을 할 때 필요로 하는 정보를 손쉽게 접근/처리 가능
- ex. `대표 전화번호`라는 환경 변수로 여러 부서에 대한 번호를 손쉽게 접근 가능
- 확인 방법
- cmd에서 `set` 명령어. `set` 누르면 모두 / `set <환경변수명>` 시 해당 변수만
- 내 PC → 속성 → 고급 시스템 설정 → 고급 탭 → 환경 변수
- **종류**
- **사용자 변수** : 로그인한 사용자에게 적용되는 환경 변수. 하나의 시스템 내에 사용자가 두 명일 때, 하나의 사용자가 지정한 사용자 변수는 다른 사용자가 접근할 수 없다.
- **시스템 변수** : 해당 시스템을 사용하는 사용자 모두에게 동일하게 적용되는 환경 변수.
- **PATH 변수** : 프로그램을 찾는 기본 경로. 변수 내 값들을 위에서부터 차례로 읽어 리턴.
- 사용자 변수와 시스템 변수 모두에 있음.
- 다른 변수와는 편집 클릭 시 다른 값의 구조를 가짐.
- _(예외)_ **시스템 변수가 사용자 변수보다 우선 적용**
- 예시
: 어떤 특정 경로에 `test.txt` 파일이 존재함. → 해당 파일을 PATH 환경 변수에 폴더 경로 추가 상황
- `cmd`에 현재 경로에서도 `test.txt` 을 찾고 있으면 실행.
- 없으면, 환경 변수 PATH를 모두 참조하여, 우선 순위에 따라 실행.
- 특징
- **사용자 변수**는 시스템 변수보다 **우선 적용**.
- 동일한 환경변수 `TEST`의 값이 다르다면 사용자 변수부터
- CORS (Cross-Origin Resource Sharing, 교차 출처 리소스 공유)

- 정의
- 브라우저가 자신의 출처가 아닌 다른 어떤 출처*(도메인, 스킴, 포트)*로부터 자원을 로딩하는 것을 허용하도록 서버가 허가해주는 HTTP 헤더 기반 메커니즘.
- 도메인이 다른 서버끼리 리소스를 주고 받을 때 보안을 위해 설정된 정책
- 예시
- 웹 사이트 A가 API 서버 B에서 데이터를 가져올 때, B에서 CORS 허용 설정이 되어있지 않으면 A에서 API 접근이 거부
- 프론트와 백이 협업하며 각자 따로 서버를 띄울 때, 서로 다른 React 서버(PORT 3000), Springboot(PORT 8080) 서버가 리소스를 주고 받으려 한다면 포트가 서로 다른 출처로 판단하여 CORS 위반 에러
- 등장 배경: SOP 정책에 따라 동일한 출처에서만 리소스를 공유할 수 있게 하여 보안을 향상 시키고 있지만, 기능상 다른 출처의 API 서버를 두거나, 다른 출처의 외부 리소스를 가져다 쓰는 경우가 있을 때의 여러 예외 조항들의 필요성 대두. 그 중 하나인 CORS 정책에 위반되지 않으면 리소스 요청 가능하게 해줌.
- 출처(Origin)의 판단 기준
- `Protocol` + `Host` + `Port 번호(생략)` 이 같은지 아닌지.
- ex. **`https://google.com:433**/map/dfjlkdjsk3432?qurey=name&page=1#first`
- 작동 방식

- 출처를 비교하여 검사하는 로직은 서버에 구현된 것이 아니라, **브라우저에 구현된 스펙 ⇒ 서버간 통신은 CORS 정책 X**

1. 웹 클라이언트 어플리케이션이 서버에 요청
- HTTP 프로토콜 사용하혀 요청
- 브라우저는 요청 헤더에 **Origin이라는 필드에 요청을 보내는 출처**를 함께
- `Origin: https//notion.so`
2. 서버는 정상적 응답

- 응답 헤더에 `Access-Control-Allow-Origin`이라는 값에 **이 리소스를 접근하는 것이 허용된 출처**를 내려줌.
- 요청을 수락할 출처를 명시적으로 지정. ⇒ 출처가 다르더라도 리소스 요청 허용

- 서버에서 응답 헤더 세팅

```jsx
'Access-Control-Allow-Origin' : <origin> | *
// * 설정 시, 출처에 상관없이 리소스에 접근할 수 있는 와일드카드이기에 보안에 취약해짐.

'Access-Control-Allow-Origin' : https://google.com
// 직접 허용할 출처를 세팅하면 좋음.
```

- 프록시 서버 사용
- 웹 애플리케이션이 리소스를 직접 요청하는 대신, 프록시 서버를 사용하여 웹 애플리케이션에서 리로스로의 요청을 전달. 동일한 출처에서 요청을 보내는 거처럼 보임.
- [`http://example.com`](http://example.com) 이라는 주소의 웹 애플리케이션이 [`http://api.example.com`](http://api.example.com)이라는 리소스에서 데이터를 요청하는 상황일 때, 웹 애플리케이션이 직접 리소스에 요청하는 대신, [`http://example-proxy.com`](http://example-proxy.com이라는) 이라는 프록시 서버에 요청을 보내어 해당 프록시 서버에서 요청을 보낸 거처럼 보이기에 CORS 에러 방지

3. 브라우저가 해당 응답을 분석해 CORS 정책 위반인지 판단 → 위반 시 응답 버림.

- 브라우저는 자신이 보낸 요청의 `Origin`과 서버 응답의 `Access-Control-Allow-Origin`을 **비교해본 후 해당 응답이 유효한 응답인지 아닌지 결정**
[https://docs.tosspayments.com/resources/glossary/cors#서버에서-access-control-allow-origin-응답-헤더-세팅하기](https://docs.tosspayments.com/resources/glossary/cors#%EC%84%9C%EB%B2%84%EC%97%90%EC%84%9C-access-control-allow-origin-%EC%9D%91%EB%8B%B5-%ED%97%A4%EB%8D%94-%EC%84%B8%ED%8C%85%ED%95%98%EA%B8%B0)
- **CORS 정책을 위반하는 리소스 요청으로 에러가 발생하여도, 서버 로그에서는 정상적으로 응답했다는 로그가 남음.**

- 교차 출처 리소스를 호스팅하는 서버가 실제 요청을 허가할 것인지를 확인하기 위해 브라우저가 보내는 사전 요청 메커니즘에 확인 _(사전 요청에서 브라우저는 실제 요청에서 사용할 HTTP 메서드, 헤더 정보가 표시된 헤더에 담아 보냄.)_

- DB Connection
- 정의
- DB와 소프트웨어가 통신할 수 있도록 해주는 데이터 중심 프로그래밍의 개념
- DB와 애플리케이션 간 통신을 할 수 있는 수단
- 구조
- 2Tier
- **클라이언트로서 자바나 노드의 프로그램(WS)**이 직접 DB 서버로 접근하여 데이터를 엑세스하는 구조
- **WS + DB**
- 3Tier
- **클라이언트로서 자바나 노드의 프로그램**과 **서버 중간의 미들웨어 층(WAS)**을 두어, **미들웨어 층에 비즈니스 로직 구현, 트랜잭션 처리, 리소스 관리** 등을 전담하는 구조
- **WS + WAS + DB**
- DB Connection Pool
- 정의 : 웹 컨테이너(WAS)가 실행되면서 일정량의 **Connection 객체**를 미리 만들어서 **pool에 저장**했다가, **클라이언트 요청으로 DBMS 작업을 수행해야하면, Connection 객체를 빌려주고** 해당 객체의 임무가 완료되면 **다시 Connection 객체를 반납받아서 pool에 저장**하는 프로그래밍 기법
- 등장 배경 : 매번 WS를 통해 DB에 직접 연결해서 처리하는 경우, 매번 사용자가 요청을 할 때마다 드라이버를 로드하고 커넥션 객체를 생성하여 연결하고 종료하기 때문에 **매우 비효율적**
- 장점
- **DB 접속 설정 객체를 미리 만들어 연결하여 메모리 상에 등록**해 놓기 때문에, **불필요한 작업(커넥션 생성, 삭제)이 사라지므로** 클라이언트가 **빠르게 DB에 접속** 가능
- **DB Connetcion 수를 제한** ⇒ 과도한 접속으로 인한 **서버 자원 고갈 방지**
- DB 접속 모듈을 공통화 ⇒ DB 서버 환경 변경 시 유지보수 용이
- Connetion을 재사용화 ⇒ 새로운 객체 만드는 비용 감소
- 단점
- 동시 접속자가 많을 경우, 커넥션 수가 제한되어 있어 반납될 때까지 대기
- 많은 커넥션 생성 시, 커넥션은 객체이므로 많은 메모리 차지 ⇒ 프로그램 성능 저하
- Connection Pool이 커지면 성능이 반드시 좋아지는 것 X
- Connection 주체는 Thread이므로 함께 고려
1. Thread Pool 크기 < Connection Pool 크기 시
- Thread Pool에서 트랜잭션을 처리하는 Thread가 사용하는 Connection 외에 남는 Connection은 메모리 공간만 차지
2. Thread Pool 크기와 Connection Pool 크기 모두 증가 시
- Thread 증가로 인한 더 많은 Context Switching 발생
- Context Switching : 하나의 프로세스가 CPU를 사용중인 상태에서 다른 프로세스가 CPU를 사용하도록 하기 위해, **이전의 프로세스의 상태를 보관하고 새로운 프로세스의 상태를 적재하는 작업 ⇒ Disk 경합 측면에서의 성능 저하 (Disk 병목 현상)**
- Connection Pool 크기
- `1connections = ((coreCount) * 2 + effectiveSpindleCount)`
- coreCount : 서버 환경 CPU 개수
- effective_spindle_count : 기본적으로 DB 서버가 관리할 수 있는 동시 I/O 요청 수
- I/O 요청 수 = 디스크의 수
- 비동기 (async, await)

- 동기 : 어떤 작업을 실행할 때 해당 작업이 끝나기를 기다리는 방식. 작업이 완료될 때까지 다음 코드의 실행을 멈추고 기다리는 방식.
- 비동기 : 어떤 작업을 실행할 때 해당 작업이 완료되지 않더라도 다음 코드를 실행하는 방식. 작업이 완료되지 않더라도 결과를 기다리지 않고 다음 코드를 실행하는 방식.
- 필요성 : JS는 Single Thread 기반의 프로그래밍 언어로, 하나의 thread에서 모든 작업을 처리하도록 되어 있기 때문에, 한 번에 하나의 작업만 처리 가능
```jsx
funcion test (동기처리 = "동기 처리") {
for (let i = 0; i < 10_000;; i++) console.log(동기처리);
console.log(1);
} // 동기 처리 시, 반복문이 10000번 돌아갈 때까지 대기
```
- 비동기 처리 시, 하나의 스레드에서 병렬적으로 여러 작업 가능
- ex. 네트워크 통신을 비동식 방식 처리 시, 서버에서 데이터를 받아오는 동안 다른 작업 처리, 데이터를 받아오는 작업이 완료될 시 해당 작업을 처리.
- 장점
- 웹 페이지 반응성 향상
- 사용자가 요청한 작업이 완료될 때까지 기다린다면, 사용자 경험 저해 ⇒ 빠르게 반응
- 웹 애플리케이션에서는 서버와의 데이터 통신이 필요한데, 이때도 웹 페이지의 성능을 향상시키는 데 도움이 됨.
- 병렬 처리 : 전체 작업 시간 단축
- 에러 처리
- 에러 발생 시, 에러를 처리할 수 있는 콜백 함수 등으로 에러를 캐치하여 처리 가능 ⇒ 프로그램 안정성
- `async`, `await` 는 ES8부터 추가된 JS 비동기 처리 방식 중 하나로, 동기 코드처럼 작성할 수 있어 가독성 향상과 에러 처리가 간단해짐.
- `async`

- 함수의 앞에 붙여서 해당 함수가 비동기 함수임을 나타내는 코드
- 항상 프로미스 반환. 프로미스가 아닌 값도 프로미스로 감싸 반환

```jsx
// 프로미스가 아닌 값이 반환될 때,
async function f() {
return 1;
}
f().then(alert); // 1을 프로미스로 감싸 반환

async function f() {
return Promise.resolve(1);
}
f().then(alert); // 1
```

- `await`

- 비동기 함수의 실행 결과를 기다리는 키워드.
- `async` 내에서 `await` 사용 시, 해당 비동기 작업이 완료될 때까지 코드 실행을 일시 중지하고 결과를 기다린 다음, 해당 결과 반환.

```jsx
async function getData () { // 비동기 함수 지정
const res = await fetch('/api'); // 해당 비동기 작업이 완료될 때까지 대기
const data = await res.json(); // res에 await 작업 후에 반환 값 불러옴. 또 대기.
return data;
}

async function f() {
let promise = new Promise((res, rej) => {
setTimeout(() -> res("완료"), 1000)
});
let result = await promise; // promise가 이행될 때까지 대기. 처리 후 실행 재개
alert(result);
}
f();
```

- try/catch/finally

- `try/catch/finally` 는 JS의 예외 처리 기법
- `catch`절은 `try` 블록 내부에서 예외 발생 시 호출되는 블록
- `catch`, `finally` 블록 생략 가능
- `try` 블록은 반드시 `catch`, `finally` 중 적어도 하나 이상의 블록과 함께 사용
- `try`
- 정상일 때, 해당 블록 내 코드 실행
- `catch(error)`
- `try` 블록에서 예외가 발생할 경우에 실행
- 지역 변수 `error`를 사용하여 Error 객체 또는 앞에서 던진 다른 값 참조 가능
- `finally`
- `try` 블록에서 일어난 일에 관계없이 무조건 실행될 코드 위치
- `try` 블록이 종료되면 실행
1. 정상적으로 `try` 블록이 끝날 때
2. `break`, `continue`, `return` 문
3. 예외가 발생했지만 `catch` 문에서 처리
4. 예외가 발생 후, 처리하지 못하고 퍼져나갈 때

```jsx
async function getData() {
// 비동기 함수 지정
try {
const res = await fetch("/api"); // 해당 비동기 작업이 완료될 때까지 대기
const data = await res.json(); // res에 await 작업 후에 반환 값 불러옴. 또 대기.
return data;
} catch (error) {
console.error(error);
}
}

// await은 Promise 객체가 완료될 때까지 코드 실행을 일시 중지하므로, try-catch 블록 내에서 사용하여 에러 처리 가능.
// fetch에서 네트워크 에러 발생 경우, await 이후의 코드는 실행하지 않으며, catch 블록으로 제어가 넘어가 에러 처리 가능
```
Loading