Giter Club home page Giter Club logo

my-study's Introduction

my-study's People

Contributors

xzcv1994 avatar

Watchers

James Cloos avatar

my-study's Issues

Map에 대한 공부

얼마전 코딩테스트를 보고 왔는데 크기 1000000000인 배열을 할당하려다 결국 할당을 못하고 코드의 엄한 부분만 무한 수정 하다가 결국 문제를 풀지 못했다.
테스트가 끝나고 같이 시험을 본 친구가 아마 크기 1000000000정도의 배열은 할당이 불가능했을거라고 map을 사용했어야 했다고 말을 해줘서 존재만 알고 있던 map에 대해 공부해보기로 했다.

map은 연관 컨테이너중 하나로 원소를 key와 value의 쌍(pair 객체)으로 저장한다고 한다.
map은 [] 연산자를 제공하여 key에 해당하는 원소의 value에 쉽게 접근하거나 변경할 수 있다.
연관 컨테이너는 빠른 원소찾기가 중요하고 균형 이진 트리를 이용해 로그시간 검색 복잡도를 보장한다고한다.
[]연산자 말고도 insert() 멤버함수로 원소를 추가할 수도 있다.
insert()함수는 반환값이 있는데 insert() 함수의 원형은

pair<iterator,bool> insert(const value_type& x);

첫번째 인자인 iterator는 현재 map의 value_type의 iterator를 가리키고 bool은 현재 값을 넣을 수 있는 상태인지 아닌지를 가리킨다.
map에서 역시 begin(), end()를 사용하여 beginning iterator, end iterator를 얻을 수 있고
erase(key)를 사용하면 map에서 key에 해당하는 원소를 삭제한다.
find(key) : key에 해당하는 iterator를 반환
count(key) : key에 해당하는 원소들의 개수를 반환
empty(0 : map이 비어있으면 true 비어있지 않으면 false를반홯
size() : 맵 원소들의 개수를 반환

마지막으로 코딩 테스트에서 배열을 이용해서 해결하지 못했던 문제를 map을 이용하여 해결하였다.

#include<iostream>>
#include<map>
#include<functional>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
//손님의 방문 순서를 배열로 입력받고 그 배열을 읽으며 쿠폰4장모아 사용한 손님을 순서대로 벡터에 저장해보자

void solution(vector<int> *v);

int main()
{
	int num; //손님의 수
	int client;
	vector<int> v1;
	vector<int> v2;
	
	cout << "손님은 몇명입니까 : ";
	cin >> num;
	
	cout << "손님이 방문한 순서대로 입력해주세요 : ";
	for (int i = 0; i < num; i++)
	{
		cin >> client;
		v1.push_back(client);
	}
	solution(&v1);
}

void solution(vector<int> *v)
{
	vector<int>::iterator iter;
	map<int,int> m;
	int check[1000] = { 0 };
	int i = 0;

	for (iter = (*v).begin(); iter != (*v).end(); ++iter)
	{
		if (m.find(*iter) == m.end())
		{
			m.insert(make_pair(*iter, 1));
		}
		else
		{
			if (0 <= m[*iter] && m[*iter] <= 2)
			{
				m[*iter]++;
			}
			else if (m[*iter] == 3)
			{
				check[i++] = *iter;
				m[*iter] = 0;
			}
		}
	}

	for (int j = 0; j < i; j++)
		cout << check[j] << " ";
}

virtual함수를 통해 비밀번호 암호화 작업을 수행 해보자

비밀번호 암호화 작업을 할 때 mongoose에서 제공하는 virtual함수를 사용하면 좀더 쉽게 작업이 가능하다.
virtual함수는 문서 객체에 실제로 저장되는 속성이 아니라 가상의 속성을 지정한다고 한다.
virtual함수로 가상속성을 지정하면 set()메소드와 get()메소드를 사용할 수 있다.

function createUserSchema(){

//스키마 정의
UserSchema = mongoose.Schema({
id : {type : String, required : true, unique : true, 'default' : ' '},
hashed_password : {type : String, required : true, 'default' : ' '},
salt : {type : String, required : true},
name : {type : String, index : 'hashed', default : ' '},
age : {type : Number, default : -1},
created_at : {type : Date, index : {unique : false}, 'default' : Date.now},
updated_at : {type : Date, index : {unique : false}, 'default' : Date.now}
});

//가상 속성 정의
Userschema.virtual('password').set(function(password){
this._password = password;
this.salt = this.makeSalt();
this.hashed_password = this.encryptPassword(password);
}).get(function(){return this._password});

//스키마 객체의 method()를 사용해  모델 인스턴스객체에서 호출할 수 있는 메소드로 추가
UserSchema.method('encryptPassword',function(plainText, inSalt){
if(inSalt){
return crypto.createHmac('sha1', inSalt).update(plainText).digest('hex');
}else{
return crypto.createHmac('sha1', this.salt).update(plainText).digest('hex');
}});

UserSchema.method('makeSalt', function(){
return Math.round(new Date().valueOf() * Math.random())) + '';
});

UserSchema.mathod('authenticate', function(plainText, inSatlt, hashed_password){
if(inSalt)
{
console('authenticate 호출됨');
return this.encryptPassword(plainText, inSalt) == hashed_passsord;
}
});

퀵정렬

까먹을때쯤 짜본 코드이다
이쁜 코드를 짜고싶습니다.

void quick_sort(int *data, int start, int end)
{
	if (start >= end)
	{
		return;
	}

	int pivot = start;
	int left = start+1;
	int right = end;
	int i;
	int temp;

	while (left <= right)
	{
		while (left <= end && data[left] <= data[pivot])
		{
			left++;
		}

		while (right > start && data[right] > data[pivot])
		{
			right--;
		}

		if (left > right)
		{
			temp = data[pivot];
			data[pivot] = data[right];
			data[right] = temp;			
		}
		else
		{
			temp = data[left];
			data[left] = data[right];
			data[right] = temp;
		}
	}

	quick_sort(data, start, right - 1);
	quick_sort(data, left, end);
}

Websocket 과 socket.io에 대해 공부

https://d2.naver.com/helloworld/1336
https://poiemaweb.com/nodejs-socketio
를 참고 하며 이해하며 정리를 해보겠다.

websocket : 실시간 상호작용하는 웹 서비스를 만드는 표준기술
client와 server사이의 동적인 양방향 연결채널을 구성하는 HTML5 프로토콜
HTTP는 클라이언트에 의해 초기화되어 서버가 변경사항을 클라이언트에게 알릴 수 있는 방
법이 없지만 WebSocket의 연결은 HTTP 통신과 다르게 클라언트가 특정 주기를 가지고
Polling하지 않아도 변경된 사항을 시기 적절하게 전달할 수 있는 지속적이고 완전한 양방향
연결 스트림을 만들어 주는 기술이다.
socket.io 다양한 방식의 실시간 웹 기술을 손쉽게 사용할 수 있게 해줌.

상호작용하는 웹서비스를 위해 숨겨진 프레임을 이용한 방법,Long Polling,Stream등 다양한 방법을
사용했으나 이러한 방식은 브라우저가 HTTP 요청을 보내고 웹서버가 이요청에 대한 HTTP응답을 보내는 단방향 메세지 교환 규칙을 변경하지 않고 구현하여 복잡하고 어려운 코드로 구현해야 했다.

그래서 보다 쉽게 상호작용하는 웹페이지를 만들기 위해 브라우저와 웹서버 사이에 더 자유로운 양방향 메시지 송수신이 필요했고 HTML5 표준안의 일부로 Websocket API가 등장했다.

표준 WebSocket 프로토콜
표준 WebSocket의 API는 W3C에서 관장하고, 프로토콜은 IETF에서 관장한다. 그리고 WebSocket은 다른 HTTP 요청과 마찬가지로 80번 포트를 통해 웹 서버에 연결한다.
HTTP프로토콜의 버전은 1.1이지만 다음 헤더의 예에서 볼 수 있듯이, Upgrade 헤더를 사용하여 웹서버에 요청한다.
GET /... HTTP/1.1
Upgrade: WebSocket
Connection: Upgrade
브라우저는 Upgrade:WebSocket 헤더 등과 함께 랜덤하게 생성한 키를 서버에 보낸다
웹 서버는 이 키를 바탕으로 토큰을 생성한 후 브라우저에 돌려준다. 이러한 고정으로 WebSocket 핸드쉐이킹이 이루어진다고 한다.
그 뒤에 Protocol Overhead 방식으로 웹서버와 브라우저가 데이터를 주고 받는다. Protocol Overhead 방식은 여러 TCP 커넥션을 생성하지 않고 하나의 80번 포트 TCP커넥션을 이용하고, 별도의 헤더 등으로 논리적인 데이터 흐름 단위를 이용하여 여러 개의 커넥션을 맺는 효과를 내는 방식이다.
이러한 방식을 이용하기 때문에 방화벽이 있는 환경에섯도 무리 없이 WebSocket을 사용할 수 있다.
Socket.io
socket.io는 현재 바로 사용할 수 있는 기술이다. socket.io는 javascript를 이용하여 브라우저 종류에 상관없이 실시간 웹을 구현할 수 있도록 한 기술
socket.io는 websocket, flashsocket, ajax long polling ajax multi part streaming iframe, jsonp polling을 하나의 api로 추상화한 것이다.
즉 브랑저와 웹서버의 종류와 버전을 파악하여 가장 적합한 기술을 선택하여 사용하는 방식

Node.js로 세션 관리법

node.js에서 session에 관련된 부분은 express를 설치해서 사용할 수 있다.
express.js에서는 크게 2가지의 방법으로 session을 활용가능하다.
1.쿠키를 이용하는 방법
2.백엔드의 세션저장소를 이용하는 방법
두가지 모두 request에 session이라는 이름으로 추가되고 session변수로 활용할 수 있다고 한다.

1.쿠키를 이용하는 방법
유저 브라우저의 쿠키를 이용하는 방법, express의 세션설정에서 cookieSession으로 설정하면 이용할 수있다. cookieParser를 이용해서 로드할 수 있다. 이 설정은 보안을 주의해야 한다고한다.
쿠키를 설정할 때 적어도 signed HttpOnly로 해야한다고 한다.
cookie-session은 설정방법이 심플하고 잘동작하지만, 크고 복잡한 민감한 데이터에 사용하는 것을 추천하지 않는다.
기본적으로 쿠키를 이용해서 사용자에 의한 변조 가능성도 높고 브라우저의 쿠키용량때문에 제한이 있을 수도 있고, 다수의 큰 용량의 쿠키는 웹사이트의 성능에 영향을 끼칠 수도 있다.

2.백엔드의 세션 저장소 이용 방법
1)memory store
2)redis store
3)mongo store
세가지 방법이 있다.

memory store
express에서 session을 설정할 때 따로 언급하지 않으면 기본적으로 memory store를 한다고 한다.
어플리케이션의 메모리에 세션 데이터를 저장, 별도의 DB가 없어도 쉽게 사용가능하다.
간단한 작업에서 임시로 사용하기 좋지만 몇가지 이유 때문에 실제 사용하는데는 비추천이라고 한다.

1.세션의 사용량이 증가하면 메모리 소비량이 증가.
2.서버 또는 어플리케이션이 어떤 이유로 재시작하게 되면 모든 데이터가 사라짐
3.세션 데이터를 분석하거나 공유할 수 없다.

redis store
redis는 key value값을 저장할 수 있는 인기 있는 메모리기반 DB이다. 이 DB는 성능과 안정성이 우수하다.

$ npm install connect-redis
위와 같은 간단한 명령어로 간단히 설치 가능

mongo store
mongoDB를 사용한다면 추천할 만한 방식 성능과 안정성 좋음
$ npm install connect-mongo

var express = require('express');
var session = require('express-session');
var MongoStore = require('connect-mongo')(session);
var mongoUrl = "mongodb://localhost:27017/test";
app.use(session({
  secret: 'keyboard cat',
  store: new MongoStore({
    url:mongoUrl,
    ttl: 60*60*24*7  // 7 days (default: 14days)
  })
}));
app.use(function(req, res, next){
  var username = "사용자이름";
  req.session.username = username;
  next();
});

위와 같이 설정하면 username이 실시간으로 session에 저장된다.

참고 자료
http://html5around.com/wordpress/tutorials/node-js%EC%97%90%EC%84%9C-%EC%84%B8%EC%85%98sessioin-%EA%B4%80%EB%A6%AC-%EB%B0%A9%EB%B2%95/

Session 이란

세션의 정의
1.망 환경에서 사용자 간 또는 컴퓨터 간의 대화를 위한 논리적 연결
2.프로세스들 사이에서 통신을 하기 위해 메시지 교환을 통해 서로를 인식한 이후부터 통신을 마칠 때까지의 기간

<구글링하다 찾은 명료한 설명>
세션이랑 일정 시간동안 같은 사용자(정확히는 브라우저)로 부터 들어오는 일련의 요구를 하나의 상태로 보고 그 상태를 일정하게 유지시키는 기술이라고 한다.
이때 일정 시간이란 방문자가 웹 브라우저를 통해 웹서버에 접속한 시점으로부터 웹 브라우저를 종료함으로써 연결을 끝내는 시점을 말한다.

<쿠키와 세션의 차이점>
*쿠키 : 쿠키는 특정 웹사이트를 방문 했을때 만들어지는 정보를 담는 파일을 지칭하는것을 쿠키라고한다. 방문자의 정보를 방문자의 컴퓨터의 메모리에 저장하는것
*세션은 방문자의 요청에 따른 정보를 웹 서버에 세션 아이디 파일을 만들어 서비스가 실행되고 있는 서버에 저장하는 것

<HTTP session 이란>
1.session 은 서버가 해당 서버(웹)로 접근(request)한 클라이언트(사용자)를 식별하는 방법
2.서버(웹)는 접근한 클라이언트(사용자)에게 response-header field인 set-cookie 값으로 클라이어트 식별자인 session-id를 발행(응답)한다.
3.서버로부터 발행(응답)된 session-id는 해당 서버(웹)와 클라이언트(브라우저) 메모리에 저장된다. 이때 클라이언트 메모리에 사용되는 cookie타입은 세션 종료시 같이 소멸되는 'memory cookie'가 사용된다.
4.서버로부터 발행된 session(데이터)을 통해 개인화(사용자)를 위한 데이터로 활용할 수 있다.

<HTTP session 동작순서)
1.클라이언트가 서버로 접속(http요청)을 시도한다.
2.서버는 접근한 클라이언트의 request-header field인 cookie를 확인해 클라이언트가 해당 session-id를 보내왔는지 확인한다.
3.만약 클라이언트로 부터 발송된 session-id 가 없다면, 서버는 session-id를 생성해 클라이언트에게 response-header field인 set -cookie갑으로 session-is를 발행한다.

참고사이트 :
[네이버 지식백과] 세션 [session] (용어해설)
http://cafe.naver.com/metroapp/113
http://mohwaproject.tistory.com/176
http://citylock.tistory.com/446
http://88240.tistory.com/190
http://88240.tistory.com/190 [shaking blog]

app.use 란?? 미들웨어란??

app.use()

app.use()는 미들웨어 기능을 마운트하거나 지정된 경로에 마운트하는 데 사용된다.
기본 경로가 일치하면 미들웨어 기능이 실행된다.
app.use() 는 Express 앱에서 미들웨어 역할
app.get(), app.post()등과 달리 요청 URL을 지정하지 않아도 app.use()를 사용할 수 있으며 해당 경우에는 URL에 상관없이 매번 실행된다.
app.use() 및 app.Method() 함수를 이용해 응용프로그램 수준의 미들웨어를 app객체의 인스턴스에 바인딩
Method = get or post

미들웨어

구조 내에서 중간 처리를 위한 함수를 말한다.(모듈은 함수들의 모임)
express 프레임워크 구조 내에서 처리 목적으로 사용한다.
요청에 대한 응답 완료전 중간중간 다양한 일을 처리가능하다.
request-response 주기로 종료된다.
먼저 로드되는 미들웨어 함수가 먼저 실행

미들웨어 함수 유형 및 사용

미들웨어가 다뤄지는 영역마다 조금씩 정의의 차이가 있다.

  1. 어플리케이션 : 어플리케이션 전체 영역에서 처리 가능하다, 앱에 대한 request가 발생할 때마다 실행된다. ex) app.use(), app.Method()
  2. 라우터 : 라우터 단위로 request가 발생하면 실행, 특정 지정 라우트가 실행되었을 때마다 실행되는 미들웨어
  3. 에러 핸들링 : 에러가 발생하면 핸들링할 때 사용하는 미들웨어
  • 에러 핸들링 미들웨어는 4개의 인수(err, req, res, next)를 가짐

  • 에러가 캐치되면
    app.use(function(req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
    });
    위의 미들웨어 함수가 호출된다. app.use(function())처럼 아무런 url이 지정되어있지 않으므로 지정된 url이외에는 모두 에러로 처리하겠다는 것이다.
    next(err);이 호출되며
    app.use(function(err, req, res, next) {
    // set locals, only providing error in development
    res.locals.message = err.message;
    res.locals.error = req.app.get('env') === 'development' ? err : {};

// render the error page
res.status(err.status || 500);
res.render('error');
});
가 호출된다. 에러캐치와 에러 메시지를 분석하여 렌더링 하는 함수가 나뉘어 있다.
4. 써드파티 미들웨어

[출처]https://jinbroing.tistory.com/126

쿠키를 처리하기

익스프레스에서는 cookie-parser 미들웨어를 사용하면 쿠키를 설정하거나 확인할 수 있다.
use()메소드를 사용해 cookie-parser미들웨어를 사용하도록 만들면 요청 객체에 cookies속성이 추가됩니다.

router.route('/process/showCookie').get(function(req,res){
res.send(req.cookies); // 요청객체의 cookie정보를 response객체에 담아 전송
});

router.route('process/setUserCookie').get(function(req,res){

res.cookie('user',{
id : 'mike',
name : '트와이스',
authorized : true
}); // 응답객체의 cookie() 메소드를 통해 user쿠키를 추가한다.
       쿠키가 클라이언트 웹브라우저에 설정됨.

res.redirect('/process/showCookie);
});

세션 처리하기

세션을 통해 로그인/로그아웃 접근제한 하기

var cookieParser = require('cookie-parser');
var expressSession = require('express-session');

app.use(cookieParser());
app.use(expressSession({
        secret : 'my key',
        resave : true,
        saveUninitialized : true
}));

router.route('/process/product').get(function(req,res){ //상품페이지로 이동시도
 console.log('/process/product 호출됨.');

 if(req.session.user){ //로그인이 되어있는지 세션에 user정보가 저장되어있는지 확인
  res.redirect('/public/product.html');
} else{
  res.redirect('/public/login2.html');
}
});
app.use('/',router);

router.route('/process/login').post(function(req,res){
var paramId = req.body.id || req.query.id;
var paramPassword = req.body.password || req.body.password;

if(req.session.user){
  console.log('이미 로그인 되어 있습니다.');

  res.redirect('/public/product.html');
} else{ 
req.session.user = { //세션저장
id : paramId,
name : '트와이스',
authorized : true
};

console.log('login success');
}
});  

router.route('/process/logout').post(function(req,res){

if(req.session.user) //로그인된 상태
{
  console.log('로그아웃 합니다.');

  req.session.destroy(function(err){
  if(err){throw err;}

  console.log('세션을 삭제하고 로그아웃함');
  res.redirect('/public/login2.html');
});
} else{
console.log('아직 로그인 되어있지 않습니다.
res.redirect('/public/login2.html');
}
});

단순 용어 정리

아무래도 모든 용어들의 정의를 기억할순 없으니 용어정리를 틈틈히 하면 좋을것 같다.

HTTP

: WWW상에서 정보를 주고받을 수 있는 프로토콜 TCP와 UDP사용 80번 포트를 사용
클라이언트와 ㅅ버사이에 이루어지는 요청/응답 프로토콜, 클라이언트인 웹브라우저가 HTTP를 통해 서버로부터 웹페이지나 그림정보를 요청하면 서버는 이요청에 응답하여 필요한 정보를 해당 사용자에게 전달하게 된다.
출처 : 위키백과

HTTPS

: HTTP의 보안이 강화된 버전, 통신의 인증과 안호화를 위해 개발됨
소켓 통신에서 일반텍스트를 이용하는 대신 SSL,TLS 프로토콜을 통해 세션 데이터를 암호화 한다
HTTPS의 기본 TCP/IP 포트는 443번

시리얼 통신

시리얼 통신 또는 직렬통신은 1개의 통로로 1bit씩 순차적으로 보내는 통신방식을 말한다.
병렬통신에 비해 구축이 간편하고, 비용을 절감할 수 있으며 먼거리 까지 전송가능하다는 장점을 가지고 있다.
동기 시리얼 통신, 비동기 시리얼 통신 두 종류가 있다.

프레임 워크

: SW의 구체적인 부분에 해당하는 설계와 구현을 재사용이 가능하게끔 일련의 협업화된 형태로 클래스들을 제공하는것(랄프 존슨)
-프레임 워크의 종류 : 자바(Struts, Spring, 전자정부 프레임워크)
QRM(myBatis, Hibernate), 자바스크립트(Angular.JS, React), 프론트엔드 프레임 워크(Bootstrap,MDL)
-프레임 워크의 장점 :
1.효율적이다. 시간과 비용이 훨씬 절약되고 생산성이 좋아진다.
2.Quality 향상. 다수의 개발자가 사용하며 수정한 코드로 이미 검증된 코드라고 볼 수 있다.
3.유지보수 용이. 코드가 체계적이기 때문에 담당자가 바뀌어도 위험부담을 줄일 수 있고 유지보수에 안정적이다.
-프레임 워크의 단점 :
1.학습시간이 길다. 프레임 워크의 코드를 배우는데 시간이 걸린다.
2.제작자가 설계한 구조를 유지하며 코드에 살을 붙여야 하기 때문에 자유도와 유연성에 있어서 한계가 있다.

POJO

Plain Old Java Object의 약자 말그대로 오래된 방식의 간단한 자바 오브젝트라는 말.
상속, 인터페이스가 필요없는 아주 단순하고 가벼운 객체를 의미
Java EE등의 중량 프레임워크들을 사용하게 되면서 해당 프레임워크에 종속된 무거운 객체들을 만들게 된 것에 반발하여 사용하게 된 용어

스프링 프레임 워크

자바 엔터프라이즈 개발을 편하게 해주는 경량급 오픈소스 애플리케이션 프레임워크이다.
자바 플랫폼을 위한 오픈소스 애플리케이션 프레임 워크
동적인 웹사이트 개발을 위한 여러가지 서비스를 제공한다.
전자 정부 표준 프레임워크의 기반 기술
POJO기반의 Enterprise Application개발을 쉽고 편하게 할 수 있도록 하는것을 목적으로한다.
Java Application을 개발하는데 필요한 하부구조를 포괄적으로 제공한다.
spring이 하부구조를 처리하기 때문에 개발자는 Application 개발에 집중할 수 있다.
-주요 특징
-DI(Dependency Injection)의존 관계 주입
각각의 계층이나 서비스들 간에 의존성이 존재할 경우 Spring이 서로 연결시켜준다.
POJO 객체들 사이의 의존 관계를 Spring이 알아서 연관성을 맺어준다.
-AOP(Aspect Orientated Programming)관점 중심 프로그래밍'
spring은 핵심적인 비즈니스 로직과 관련이 없으나 여러 곳에서 공통적으로 쓰이는 기능들을 분리하여 개발하고 실행 시에 서로 조합할 수 있는 AOP를 지원한다.
이를 통해 코드를 단순하고 깔끔하게 작성할 수 있다.
-Portable Service Absraction이식 가능한 서비스 추상화
Spring은 완성도가 높은 라이브러리와 연결할 수 있는 인터페이스를 제공한다.
즉, 다른 프레임워크들과의 통합을 지원한다.
참고 : https://gmlwjd9405.github.io/2018/10/26/spring-framework.html

세션

일정 시간동안 같은 사용자로 부터 들어오는 일련의 요구를 하나의 상태로 보고 그 상태를 일정하게 유지시키는 기술이다. 방문자의 요청에 따른 정보를 방문자 메모리에 저장하는 것이 아닌 웹 서버가 세션 아이디 파일을 만들어 서비스가 돌아가고 있는 서버에 저장하는 것이다. 서버에 저장되기 때문에 사용자 정보가 노출되지 않는다.
원리
세션 ID를 서버에서 클라이언트가 자신의 웹사이트에 접속시 발급
서버에서 클라이언트로 발급한 세션 ID를 쿠키를 사용해서 저장
클라이언트는 다시 접속시 이 쿼리를 이용해서 세션 ID값을 전달
장점
각 클라이언트에게 고유 ID를 부여한다.
세션ID로 클라이언트를 구분해서 클라리언트의 요구에 맞는 서비스를 제공 가능
사용해온 정보들을 서버에 저장하여 쿠키보다 보안성이 우수
단점
서버에 저장되어 서버에 처리 요구하는 부하와 저장 공간을 필요로한다.

쿠키

쿠키란 서버측에서 클라이언트 측에 상태 정보를 저장하고 추출할 수 있는 메커니즘
클라이언트의 매 요청마다 웹 브라우저로부터 서버에게 전송되는 정보패킷의 일종
HTTP에서 클라이언트의 상태 정보를 클라이언트의 하드 디스크에 저장하였다가 필요시 정보를 참조하거나 재사용 가능
웹 상에서 사용자 식별, 사용자 정보 유지에 도움
세션 유지에 사용

MVC 모델

같은 모델의 서브시스템에 대하여 여러 뷰 서브시스템을 필요로 하는 상호 작용 시스템에 적합
Model, View, Controller 3개의 서브시스템으로 분리하는 이유 : 변경에 대한 영향을 덜 미치도록 하려는 것
즉 사용자 인터페이스 부분이 자주 변경되더라도 모델 서브시스템에는 영향을 주지 않기 위해서이다.
1.Model
View/Control 서브시스템과 독립되어 모든 데이터 상태와 로직을 처리 MVC 모델의 웹 애플리케이션에서는 Controller가 모델을 호출하는 역할

2.View
웹 애플리케이션의 사용자와 직접 대화가 이루어지는 부분 Model 서브시스템이 제공한 데이터를 사용자에게 보여주는 역할, 즉 모델로부터 얻은 데이터를 표현하는 방법을 제공하고 다양한 뷰를 통해 표시, 뷰마다 Controller 서브시스템이 각각 하나씩 연결된다.

3.Controller
View 와 Model 사이에서 전달자 역할, 즉 View를 통한 사용자의 요청을 적절한 Model로 넘겨주고 Model로 부터 받은 응답을 다시 View로 사용자에게 돌려줌

장점
로직과 데이터등 어플리케이션을 세부분으로 분리하여 더 이해하기 쉬워지고 부속간의 의존성 감소
개발자들은 특정 영역에 특화되는 경우가 많은데 특정 코드에만 집중할 수 있도록 업무를 분할 할 수 있다.
MVC 사용시 로직에 영향을 주지 않고 화면 표시를 수정할 수 있다.
MVC 사용시 호면 표시에 영향을 주지 않고 로직을 수정할 수 있다.
MVC를 사용하면 뷰 구현을 수정하지 않고 사용자 동작에 반응하는 코드를 수정할 수 있다.

단점
기본기능 설계를 위해 클래스들이 많이 필요하기 때문에 복잡할 수 있다.
설계시간이 오래 걸리고 숙련된 개발자가 필요하다
Model과 View의 완벽한 분리가 어렵다.

미들웨어

정의
-응용소프트웨어가 운영체제로부터 제공받는 서비스 이외에 추가적으로 이용할 수 있는 서비스를 제공하는 컴퓨터 소프트웨어
-양 쪽을 연결하여 데이터를 주고받을 수 있도록 중간에서 매개 역할을 하는 소프트웨어
-네트워크를 통해서 연결된 여러 개의 컴퓨터에 있는 많은 프로세스들에게 어떤 서비스를 사용할 수 있도록 연결해주는 소프트웨어
동작환경
DB, 네트워크, 운영체제, 유저인터페이스 등과 Business Ware(각종 툴, 패키지등)의 중간에 위치

장점
-표준화된 인터페이스 제공 가능
-다양한 환경 지원, 체계가 다른 업무와 상호 연동이 가능
-분산된 업무를 동시에 처리 가능하여 자료의 일관성이 유지
-클라이언트 쪽에 비즈니스 로직이 많을 경우, 클라이언트 관리(배포 등)로 인해 비용이 많이 발생하는데 --비즈니스 로직을 클라이언트와 DBMS 사이의 미들웨어 서버에서 동작하도록 하면 클라이언트는 입력과 출력만 담당하면 된다.
-미들웨어를 사용함으로써 네트워크 프로토콜이나 운영체제에 관계없이 동일한 애플리케이션을 사용가능

종류
-원격 프로시저 호출(Remote Procedure Call, RPC) : 클라이언트가 원격에서 동작하는 프로시저를 호출하는 시스템, 동기 또는 비동기 지원
-메시지 지향 미들웨어(Message Oriented Middleware, MOM) : 클라이언트가 생성한 메시지는 저장소에 요청할 때 저장하면서, 다른 업무를 지속할 수 있도록 하는 비동기식 미들웽어
-ORB(Object Request Broker) : 객체지향 시스템에서 객체 및 서비스를 요청라고 전송할 수 있도록 지원하는 미들웨어
-DB 접속 미들웨어 : 애플리케이션과 데이터베이스 서버를 연결해주는 미들웨어
-TP 모니터 미들웨어 : 분산 시스템의 애플리케이션을 지원하는 미들웨어 주로 C/S 시스템에 사용
-웹 애플리케이션 서버(Web Application Server) : 웹 애플리케이션을 지원하는 미들웨어
-엔터프라이즈 서비스 버스 : 메시지 기반으로 느슨한 결합형태의 표준 인터페이스 통신을 지원

프로세스

컴퓨터에서 주메모리 상에 올라와 실행되고 있는 프로그램의 인스턴스
운영체제로부터 시스템 자원을 할당받는 작업의 단위

프로세스가 할당 받는 시스템 자원
-CPU시간
-운영을 위한 주소 공간
-Code, Data, Stack, Heap의 구조로 되어있는 독립된 메모리 영역

특징
-프로세스는 각각 독립된 메모리 영역(Code,Data,Stack,Heap)을 할당받는다.
-기본적으로 프로세스당 최소 1개의 스레드(메인 스레드)를 가지고 있다.
-각프로세스는 별도의 주소 공간에서 실행되며, 한 프로세스는 다른 프로세스의 변수나 자료구조에 접근할 수 없다.
-한 프로세스가 다른 프로세스의 자원에 접근하려면 프로세스 간의 통신(IPC, inter-process)을 사용해야 한다.

스레드

프로세스 내에서 실행되는 여러 흐름의 단위
프로세스의 특정한 수행경로
프로세스가 할당받은 자원을 이용하는 실행의 단위

특징
-스레드는 프로세스 내에서 각각 stack만 따로 할당받고 Code,Data,Heap 영역은 공유한다.
-스레드는 한 프로세스 내에서 동작되는 여러 실행의 흐름으로, 프로세스 내의 주소 공간이나 자원들(힙 공간 등)을 같은 프로세스 내에 스레드끼리 공유하면서 실행된다.
-같은 프로세스 안에 있는 여러 스레드들은 같은 힙 공간을 공유한다. 반면에 프로세스는 다른 프로세스의 메모리에 직접 접근할 수 없다.
-각각의 스레드는 별도의 레지스터와 스택을 갖고 있지만, 힙 메모리는 서로 읽고 쓸 수 있다.
-한 스레드가 프로세스 자원을 변경하면, 다른 이웃 스레드도 그 변경 결과를 즉시 볼 수 있다.

자바의 스레드
-일반 스레드와 거의 차이가 없고, JVM가 운영체제의 역할을 한다.
-자바에는 프로세스가 존재하지 않고 스레드만 존재, 자바 스레드는 JVM에 의해 스케줄되는 실행 단위 코드 블록
-자바에서 스레드 스케줄링은 전적으로 JVM에 의해 이루어진다.
-JVM이 관리하는 스레드와 관련된 정보

  1. 스레드가 몇개 존재?
  2. 스레드로 실행되는 프로그램 코드의 메모리 위치는 어디?
  3. 스레드의 상태는 무엇?
  4. 스레드 우선순위는 얼마?

-개발자는 자바 스레드로 작동할 스레드 코드를 작성, 스레드 코드가 생명을 가지고 실행을 시작하도록 JVM에 요청하는 일 뿐

멀티스레드

ㄱㄱ

디버깅

-문제가 발생 했을때 문제의 원인을 찾아 분석하고, 분석한 결과를 토대로 문제를 해결하는 과정을 말함
-발견된 버그가 어디서 발생했는지, 또 그것을 제거하는일
-버그를 찾아 해결하고 수정하는 것
-일반적으로 디버깅에는 브레이킹 포인트와 디버그 모드를 이용한 코드상의 체크
-특정 변수에 대해 조사하기 위해 해당변수의 주소값을 취해 주소의 메모리를 조사하는 메모리 디버깅
-원격지에서 디버깅하는 원격디버깅
-메모리의 상태를 확인하는 메모리 덤프
-오류 정보에 대한 기록을 확인하는 로그분석

오류의 종류
-문법적 오류 : 해당 프로그래밍 언어의 문법에 맞지 않는 코드가 있을 경우 발생, 대체로 문법적 오류는 IDE로 해결가을
-논리적 오류 : 문법적으론 문제가 없지만 의도와 맞지 않게 프로그램이 돌아가는 오류 IDE 기능만으로는 해결X


##ELB란
Elastic Load Balancing의 약자 시스템에 가해지는 부하를 여러대의 시스템에 가해지는 부하를 여러대의 시스템으로 분산해서 규모있는 시스템을 만들 수 있도록 해주는 단일 진입점

특징
트래픽분산/자동 확장/인스턴스의 상태를 자동 감지해서 오류가 있는 시스템은 배제/사용자 세션을 특정 인스턴스에 고정/SSL 암호화 지원/SSL의 경유지로 ELB를 사용하는 경우에 SSL 처리에 따른 부하를 ELB가 수용/IPv4,IPv6 지원/CloudWatch를 통해서 모니터링/사용한 시간과 통과한 트래픽에 따라서 종량제로 과금

주의사항
ELB에 EC2를 붙이면 EC2는 클라이언트와 직접 통신을 하지 않고 ELB를 경유해서 통신하게 된다. 따라서 EC2의 입장에서는 클라이언트의 IP, User-Agent, 플토콜(http,https)를 파악할 수 없다. 이문제를 해결하기 위해서 X-Forwarded-For라고하는 특수한 HTTP 헤더를 전달한다. 이 헤더의 값을 통해서 ELB로 접근한 클라이언트의 원래 IP, User-Agent, 프로토콜 등을 파악할 수 있다. 이에 대한 자세한 사항은 ELB 메뉴얼을 참고한다.

참고 : https://opentutorials.org/course/608/3008

DP알고리즘 공부2

DP알고리즘 공부를 위해 백준문제를 하나 더 풀어보았다.
https://www.acmicpc.net/problem/11055

#include<iostream>
using namespace std;

int main()
{
	int seq[1000];
	int sum[1000] = { 0 };
	int size;
	int summax = 0;
	int max = 0;
	int check = 0;

	cin >> size;

	for (int i = 0; i < size; i++)
		cin >> seq[i];

	for (int i = 0; i < size; i++)
	{
		if (i == 0)
			sum[i] = seq[i];
		else
		{
			check = i - 1;
			max = 0;
			while (check >= 0)
			{
				if (seq[check] < seq[i])
				{
					if (max <= sum[check])
					{
						max = sum[check];
						sum[i] = seq[i] + max;
						check--;
					}
					else
						check--;
				}
				else
				{
					check--;
					if (check == -1 && sum[i] ==0)
						sum[i] = seq[i];
				}
			}
		}
		
	}

	for (int i = 0; i < size; i++)
	{
		if (sum[i] > summax)
			summax = sum[i];
	}

	cout << summax;
}

패스포트

do it node.js책을 보며 요약하면서 공부했다.
패스포트는 노드에서 사용할 수 있는 사용자 인증 모듈이다.
사용자 인증 기능을 독립된 모듈 안에서 진행할 수 있도록 도와준다고 한다.
특히 익스프레스 사용시 미들웨어로 끼워 넣기가 가능해 몇가지 간단한 설정만으로도 로그인 기능을 만들 수 있다.
패스포트 모듈의 유일한 목적은 클라이언트에서 요청한 인증 정보(아이디나 비밀번호)로 사용자 인증을 하는것이다.
패스포트는 순전히 인증 기능만을 담당한다는 얘기이다.

패스포트는 수백 가지의 인증 방식을 제공하는데 이중 어떤 인증 방식을 사용할 것인지 결정하는 것을
스트래티지(strategy)라고 한다.
각각의 인증 방식은 각각의 스트래티지로 만들어져 있어 어떤 스트래티지를 사용하느냐에 따라 인증방식이 달라진다. (ex. DB에 저장된 사용자 정보와 비교하는 로컬 인증 방식, 페이스북이나 트위터의 계정을 사용하는 OAuth방식)

패스포트 인증 방식은 대략 이러하다.
1.웹 브라우저(클라이언트)에서 사용자가 사용자 인증을 할때 방식을 선택한다.(단순히 웹서버상의 DB와 비교할것인지,페이스북 또는 구글의 계정을 통해 인증할것인지 등등)
2.클라이언트가 특정 방식을 선택하여 인증을 요청한다.
3.웹 서버의 패스포트 모듈이 미리 설정해둔 인증 방식으로 사용자를 인증한 후 성공시 사용자 정보를 세션에 저장한다.(이 세션 정보는 정상적으로 사용자 인증이 되었을 시에만 사용 가능함으로 로그인 이후의 요청 정보를 처리할 때는 세션 정보를 확인함으로써 사용자의 로그인 여부를 구별할 수있다.)

router.route('/login').post(passport.authenticate('local',
{
  successRedirect: '/',           //인증에 성공했을시 리다이렉트 
  failureRedirect: '/login'       //인증에 실패했을시 리다이렉트
}
));

리다이렉트를 사용하여 응답을 보낼 때는 보통 플래시 메시지를 같이 사용한다고한다.
플래시 메시지는 상태 메시지를 응답 웹 문서 쪽으로 전달할 때 사용한다.
플래시 메시지를 사용하려면 connect-flash 외장 모듈을 사용해야 한다.
플래시 메시지를 사용하는 방법은 요청 객체의 flash() 메소드를 사용할 때 파라미터가 두 개면 플래시 메시지를 설정하는 것이고, 파라미터가 하나면 플래시 메시지를 조회하는 것

req.flash('loginMessage', '등록된 계정이 없습니다.'); //플래시 메시지 설정
req.flash('loginMessage'); //플래시 메시지 확인

failureFlash옵션
패스포트로 인증하는 과정에서 오류가 발생했을때 플래시 메시지로 오류가 전달된다.
즉 코드에서 명시적으로 req.flash()메소드를 호출하는 것이 아니라 패스포트 모듈이 자동으로 flash()메소드를 호출하며 오류 메시지를 설정한다. 이렇게 하면 필요할 때 플래시 메시지를 꺼내서 확인할 수 있다.

router.route('/login').post(passport.authenticate('local',
{
  successRedirect : '/',
  failureRedirect : '/login',
  failureFlash : true
}
));

커스텀 콜백
인증을 성공했거나 실패했을 때 어떻게 처리할 것인지를 직접 함수로 지정가능하다.

router.route('/login').get(function(req,res,next){
 passport.authenticate('local',function(err,user,info){
  if(err){return next(err);}
  if(!user){return res.redirect('/login');}
req.login(user, function(err){
return res.redirect('/users/' + user.username);
});
})(req,res,next);
});

인증이 성공하면 패스포트는 일반적으로 로그인 세션을 만듭니다. 이세션은 유용하지만 어떤 경우에는 필요하지 않습니다. 예를들어 API기능을 제공하는 서버의 경우 세션을 유지하지 않고 매 요청 마다 인증 정보를 요구하고 매 요청마다 인증을 진행하게 돕니다. 이때는 session 옵션을 false로 합니다.

스트래티지 설정과 검증 콜백
스트래티지는 사용자 아이디와 비밀번호를 사용하는 로컬 인증 방식 뿐만 아니라 OAuth나 OpenID와 같은 인증 방식까지 지원할 수 있도록 각각의 인증방식이 정의되어 있습니다.
보통 클라이언트 요청을 인증하기 전에는 스트래티지가 설정되어 있어야 하며 ,use()함수로 설정할 수 있습니다.
passport객체의 use()메소드를 사용하면 스트래터지를 설정할 수 있다.
스트래터지를 설정할 때는 검증 콜백에서 인증 결과를 처리하게 된다.
이 검증 콜백의 목적은 인증 정보들을 가지고 있는 사용자를 찾아내는 것.
클라이언트가 보내 온 요청 파라미터들을 사용해 사용자를 찾아내는 과정을 처리합니다.
사용자를 찾아내는 과정이 끝나고 성공한경우와 실패한 경우가 생기면 그 결과를 done메소드를 호출하여 알려준다. 그래야 authenticate() 메소드를 호출하는 쪽에서 실패인지 성공인지 결과를 받아볼 수 있습니다.
done메소드를 호출 하는 방식

  1. 찾아낸 사용자 정보가 유효하다.
    ->검증 콜백은 done메소드를 호출하여 패스포트에게 인증된 사용자 정보제공
    return done(null,user);
  2. 인증 정보가 유효하지 않음. ex)password가 맞지 않는 경우.
    ->done메소드 호출시 user객체 대신 false를 전달
    return done(null,false);
    2.1 인증에 실패했을 때 실패 원인을 알려주는 info 메시지를 추가로 전달할 수 있다.
    return done(null,false,{message:'비밀번호 맞지않음'});
  3. 인증 정보를 검증하는 과정에서 예외가 발생. ex)데이터베이스가 연결되지 않은 경우
    ->done메소드는 error객체를 파라미터로 전달하면서 호출
    return done(err);
    로컬인증
    설치해야할 모듈 : passport(사용자 인증처리에 필요한 기본기능 제공)
    passport-local(웹서버에서 직접 사용자의 아이디와 비밀번호를 전달 받아 DB에 저 장된 정보와 비교하는 로컬인증 기능을 제공)
    connect-flash
    passport.initialize() : 패스포트 초기화 미들웨어
    passport.session() : 로그인 세션 유지
    passport의 intialize,session함수를 호출했을때 반환되는 객체를 미들웨어로 사용할 수 있도록
    app.use(passport.initialize());
    app.use(passport.session());
    app.use()메소드를 호출하면서 initialize함수와 session함수를 호출한 결과를 파라미터로 전달
    로컬인증을 직접 구현해 보면서 작성한 코드를 보며 공부한 내용을 정리해보자
    app.js파일에 passport파일을 만들고 connectDB 함수부분에서 init를 통해 users.js에 정보를 전달 할때 passport도 전달해줬다.
    굳이 이렇게 전달안하고 users파일 안에 만들어도 될것 같지만 않해봐서 잘 모르겠다.
var passport = require('passport'); //app.js 파일에 require해서 passport 변수에 저장

app.use(passport.initialize());
app.use(passport.session());//passport모듈을 이용해 session을 관리하려면 사용해야한다고 한다.

users파일 안에서 또 Passport변수에 passport모듈을 require했다.

var Passport = require('passport');
var database;
var UserModel;
var UserSchema;
var doc;
var session;
var Passport;

/* GET users listing. */
router.get('/', function(req, res) {
  res.send('respond with a resource');
});

var init = function(db,schema,model,passport){
  console.log('init 호출됨');

database = db;
UserSchema = schema;
UserModel = model;
Passport = passport; 
}

/* user/login 라우팅 */
router.route('/login').post(Passport.authenticate('local-login',{
    successRedirect : '/users/loginsuccess', // 인증에 성공하면 redirect
    failureRedirect : '/'                    // 인증에 실패하면 redirect
}));

/* user/adduser/submit 라우팅 */
router.route('/adduser').post(Passport.authenticate('local-signup',{
    successRedirect : '/',
    //failureRedirect : '../../makeaccount.html'
}));

router.get('/loginsuccess',function(req,res){ // 이건 이제 로그인 성공하면 main2.jade에 렌더링 하기 위한 부분인데 세션의 유무를 확인해서 렌더링한다.
    if(req.session.passport.user)
        {
            res.render('main2.jade');
        }
    else
        {
            res.redirect('../../makeaccount.html'); // 세션이 없으면 회원가입 페이지로..
        }
});


var LocalStrategy = require('passport-local').Strategy; //local strategy를 사용하기 위한

Passport.use('local-login' , new LocalStrategy({ 
    usernameField : 'email',
    passwordField : 'password',
    passReqToCallback : true //이 옵션을 설정하면 아래 콜백 함수의 첫번째 파라미터로 req 객체를 전달
},function(req,email,password,done){
    console.log('passport의 local-login 호출 : ' + email + ', ' + password);
    
    database.UserModel.findOne({'email' : email},function(err,user){
        if(err){
            console.log('')
            return done(err);}
        
        if(!user){
            console.log('계정 일치하지않음');
            return done(null,false); //
        }
        
        var authenticated = user.authenticate(password,user._doc.salt,user._doc.hashed_password);
        if(!authenticated){
            console.log('비밀번호 일치하지 않음.');
            return done(null,false);  // 검증 콜백에서 두 번째 파라미터의 값을 false로 하여 인증 실패한 것으로 처리
        }
        
        console.log('계정과 비밀번호가 일치함.');
			return done(null, user);  // 검증 콜백에서 두 번째 파라미터의 값을 user 객체로 넣어 인증 성공한 것으로 처리
    });
}));


//패스포트회원가입
Passport.use('local-signup', new LocalStrategy({
    usernameField : 'email',
    passwordField : 'password',
    passReqToCallback : true
},function(req,email,password,done){
    var paramName = req.body.name || req.query.name;
    console.log('passport의 local-signup 호출');
    
    process.nextTick(function(){
        database.UserModel.findOne({'email' : email}, function(err,user){
            if(err){
                return done(err);
            }
            
            if(user){
                console.log('기존에 계정이 존재합니다.');
                return done(null,false);
            }else{
                var user = new database.UserModel({'email' : email, 'password' : password, 'name' : paramName});
                user.save(function(err){
                    if(err){
                        throw err;
                    }
                    console.log('사용자 데이터 추가완료');
                    return done(null,user);
                });
            }
        });
    });
}));

Passport.serializeUser(function(user, done) { // 인증에 성공하면 호출된다.
	console.log('serializeUser() 호출됨.');
	console.dir(user);
	
    done(null, user);  // 이 인증 콜백에서 넘겨주는 user 객체의 정보를 이용해 세션 생성
});

// 사용자 인증 이후 사용자 요청 시마다 호출됨
Passport.deserializeUser(function(user, done) {
	console.log('deserializeUser() 호출됨.');
	console.dir(user);

	done(null, user);  
});

다음엔 타사 인증도 공부하자

DP알고리즘 공부

DP알고리즘 공부차 백준 문제를 풀어보았다.
코딩을 이쁘게 잘했는지는 알 수 없다...
https://www.acmicpc.net/problem/11053

#include<iostream>
using namespace std;

int main()
{
	int check[1000] = { 0 };
	int arr[1000];
	int size = 0;
	int count = 1;
	int max;
	int kindex;

	cin >> size;

	for (int i = 0; i < size; i++)
	{
		cin >> arr[i];
	}

	for (int i = size-1; i >= 0; i--)
	{
		if (i == size-1)
		{
			check[count] = arr[size-1];
			max = count;
		}
		else
		{
			kindex = max;

			while (kindex >= 1)
			{
				if (arr[i] < check[kindex])
				{
					kindex++;
					check[kindex] = arr[i];

					if (kindex > max)
						max = kindex;
					break;
				}
				else
				{
					kindex--;

					if (kindex == 0)
						check[kindex + 1] = arr[i];
				}
			}
		}
	}

	cout << max;
}

인접행렬과 인접리스트

bfs나 dfs 할때 사용할 인접행렬과 인접리스트

인접행렬
그래프의 연결관계를 이차원 배열로 나타냄
arr[i][j] : 노드 i에서 j로 가는 간선이 존재한다면 1 아니면 0
장점 : 노드i와 노드j의 연결 여부 확인을 위해서는 arr[i][j]가 1인지 0인지만 확인하면됨 O(1)의 시간 복잡도
단점 : 노드 i에 연결된 모든 노드들에 방문하고 싶은 경우 arr[i][0]에서 arr[i][v]를 모두 확인해야한다. O(v)의 시간 복잡도, 메모리를 많이 잡아먹을 수도 있음

인접리스트
그래프의 연결관계를 vector의 배열로 나타냄. vector에 노드의 번호가 직접저장
이차원 벡터
장점 : 실제로 연결된 노드에 대한 정보만 저장하기 때문에, 간선의 개수에 비례하는 메모리만 차지
단점 : 노드i와 노드j의 연결여부 확인을 위해 arr[i] 전체를 돌며 확인해야해서 시간복잡도가 O(v)

C++과 Javascript의 변수 스코프

C++

함수 내부에 정의된 변수를 지역변수라고 하며 지역변수는 자동 주기를 가지고 있다고 한다.
정의된 시점에서 생성되고 초기화되며, 정의된 블록이 끝나는 지점에서 소멸 또한 지역변수는 지역스코프(블록스코프라고도 함)를 가진다. 이것은 선언된 시점에서 스코프에 들어가고 정의된 블록 끝에서 스코프를 벗어나는 것을 의미한다고 한다. 스코프 내에서만 변수에 접근가능
중첩 블록 내부에 정의된 변수는 중첩 블록이 끝나면 즉시 소멸
중첩 블록은 외부 블록의 일부로 간주되어 외부 블록에서 정의된 변수를 중첩 블록 내부에서 접근가능하다.

Javascript

스코프
전역 스코프와, 지역 스코프가 존재
-전역 스코프 : 변수가 함수 바깥이나 중괄호 바깥에 선언되면 전역 스코프에 정의되었다고 한다.
전역 변수 선언시 코드의 모든 곳에서 해당 변수를 사용할 수 있다. 함수내에서도 가능
-지역 스코프 : 코드의 특정 부분에서만 사용 가능한 변수를 지역 스코프에 있다고 한다. 그리고 지역 변수라 부른다.
-자바스크립트에는 두개의 지역 스코프가 존재한다.
함수 스코프
함수 내부에서 변수를 선언하면, 해당 변수는 선언한 함수 내부에서만 접근 가능합니다.
블록 스코프
중괄호 내부에서 const,let으로 변수를 선언하면, 해당 변수는 중괄호 블록 내부에서만 접근 가능하다.

참고 사이트
https://medium.com/@khwsc1
https://boycoding.tistory.com/166

vector에 대한 공부

vector를 사용하면 코딩할 때 편리한 경우가 있는것 같고 또 써야만 더 좋은 성능을 낼 수 있는 경우가 있기 때문에 vector를 공부하기로 했다.
vector는 stl의 시퀀스 컨테이너중 하나로 동적으로 배열을 할당해야 할 때 사용하면 편한것 같다.
하지만 중간에 삽입 삭제가 용이하지않고 순차적으로 데이터를 저장한다.
검색도 느린편이라고한다.

벡터의 선언
vector<data_type> v1;
이런식으로 벡터를 선언한다.
그리고

vector<int> v(10); //0으로 초기화된 10개의 원소를 가지는 vector v를 생성 
vector<int> v(7, 3) //3으로 초기화된 7개의 원소를 가지는 vector v를 생성

이런식으로 초기화를 하고

v1.push_back(data); //push_back() 함수를 이용해 vector v1의 뒷부분에 data를 추가한다.
v1[i];
v(i); //둘다 i번째에 저장된 값을 참조한다.

그리고 vector형 반환 함수를 선언할때는

std::vector<data_type> solution(vector<int> *v1)
{ ... }
//다음과 같이 작성한다.

그 밖에

v1.front(); //첫번째 원소 참조
v1.back(); //마지막 원소 참조
v1.size(); //원소갯수 반환
v1.pop_back(); //마지막 원소 제거
v1.clear(); //v1의 원소 모두 제거
v1.begin(); //첫번째 원소를 가리키고
v1.end(); //마지막 원소의 다음을 가리킨다. begin과 end는 iterator와 함께 사용한다.

실습한 내용

#include<iostream>>
#include<map>
#include<functional>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
//손님의 방문 순서를 배열로 입력받고 그 배열을 읽으며 쿠폰4장모아 사용한 손님을 순서대로 벡터에 저장해보자

void solution(vector<int> *v);

int main()
{
	int num; //손님의 수
	int client;
	vector<int> v1;
	vector<int> v2;
	
	cout << "손님은 몇명입니까 : ";
	cin >> num;
	
	for (int i = 0; i < num; i++)
	{
		cin >> client;
		v1.push_back(client);
	}

	solution(&v1);


}

void solution(vector<int> *v)
{
	vector<int>::iterator iter;

	for (iter = (*v).begin(); iter != (*v).end(); ++iter)
		cout << *iter;
}

2차원 벡터를 만들어보자

vector< vector<int> > v1; // vector<int>를 자료형으로 갖는 vector선언!
vector<int> v2; //2차원 벡터의 각 행에 들어가게 될 벡터를 선언!

for (int i = 0; i < T; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			cin >> temp; 
			v2.push_back(temp); //각 행에 들어가게될 1차원 벡터에 값을 저장하고
		}
		v1.push_back(v2); //값을 가진 1차원 벡터를 2차원벡터의 행에 push!
		v2.clear(); //1차원 벡터에는 다시 값을 넣어줘야 하니까 원소 제거
	}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.