getDate, getMonth 등으로 월이나 일을 구할 수는 있지만

특정 기간, 즉 시작날짜와 끝날짜를 입력하고 

일별 or 주별 or 월별을 선택 했을 때 그 사이의 시작날짜와 끝날짜를 반환하는 함수는 찾기 힘들었다. 

(어쩌면 내가 못찾고 하드코딩 한걸수도..?)

용도는 charts.js를 사용하기 위해서다. 

날짜로 범위를 걸어서 일별 데이터를 보거나 월별 데이터를 보는 화면을 제작해야 했다.

 

startDate <- 0월24일

endDate <- 3월15일

term <- 2

을 하면 1월24일부터 4월15일까지

주 단위로 (첫째날 포함) 기간이 나뉘어진 것이 returnData로 반환된다.

 

returnData

 

 

/* eslint-disable no-console */
const mongoose = require('mongoose');
const objectId = mongoose.Types.ObjectId;

function dateToObjectIdConvert (dateTime) {
	return objectId(Math.floor(dateTime / 1000).toString(16) + '0000000000000000');
};

function objectIdToDateConvert (objectId) {
	return new Date(parseInt(String(objectId).substring(0, 8), 16) * 1000);
};
const startDate = new Date(2020, 0, 24); // 3->4로되고 시간 설정을 안해서 00시인데 한국00시는 표준시간으로 15시라서  결과적으로 4월14일15시 값이 저장된다.
const endDate = new Date(2020, 3, 15);
const term = 2;
let offset = 0;
console.log(`startDate is ${startDate}, term is ${term}`); // 4월14일15시 값을 +9한 한국시간으로 출력
// console.log(startDate); // 저장되있는 4월14일15시 값 츨력
if (term === 1) {
	offset = 1;
} else if (term === 2) {
	const toMonday = (startDate.getDay() === 0) ? 6 : startDate.getDay() - 1;
	startDate.setDate(startDate.getDate() - toMonday);
	offset = 7;
} else if (term === 3) {
	startDate.setDate(1);
}

const returnData = [];
while (startDate < endDate) {

	const startId = dateToObjectIdConvert(new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate()).getTime());
	if (term === 3) {
		offset = (new Date(startDate.getFullYear(), startDate.getMonth() + 1, 0)).getDate();
	}
	const endId = dateToObjectIdConvert(new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate() + offset).getTime());

	returnData.push({ start: objectIdToDateConvert(startId), end: objectIdToDateConvert(endId) });
	startDate.setDate(startDate.getDate() + offset);
}
console.log(returnData);

+나중에 괜찮으면 npm 서버에도 올리기

db에 저장되는 시간값은 표준시간이다. (쉽게 말해 콘솔의 저 보라색 줄..)

getDay와 같은 메소드는 서버시간 기준으로 출력을 하고 입력을 하는데

나는 이 말이 코드 짜다보면 너무 헷갈렸다.

완전히 익숙해지기 전까진, 수시로 시간을 콘솔로 출력해보고

이 글을 다시 보면서 내가 생각한대로 날짜가 처리되는지 확인을 해야겠다.

날짜를 기준으로 데이터를 처리하는 경우가 매우 빈번하고, 데이터에 따라서

하루 차이가 꽤 크게 날 수도 있기 때문이다. 

let startDate = new Date(2020, 3, 15); // 3->4로되고 시간 설정을 안해서 00시인데 한국00시는 표준시간으로 15시라서  결과적으로 4월14일15시 값이 저장된다. 
let endDate = new Date(2020, 5, 15);
let term = 2;
let offset = 0;
console.log(`startDate is ${startDate}, term is ${term}`); // 4월14일15시 값을 +9한 한국시간으로 출력
console.log(startDate); // 저장되있는 4월14일15시 값 츨력
if (term === 1) {
	offset = 1;
} else if (term === 2) {
	console.log(startDate.getMonth()); // get으로 month만 따로 출력하는건 -1한 값인 3으로 출력
	console.log(new Date(startDate.getFullYear(), startDate.getMonth(), 0)); // new Date로 생성됨에 주의. getMonth가 3인데 입력될땐 3->4로 저장되는 것을 첫 줄에서 확인했다. 1일이 아니라 0일이라서 3월31일00시되고 표준으로 -9시니까 30일 15시로 값이 저장된다. (사실 생성만 되고 바로 getDate로 출력됨).아마 getDate하면 31로 나올 것
	console.log((new Date(startDate.getFullYear(), startDate.getMonth(), 0)).getDate()); // 31
	console.log(startDate.getMonth()); // 4월로 값이 들어가 있으니 출력은 3
	console.log(startDate.getDate()); // 한국시간으로 15일
	console.log(startDate.getDay()); //한국시간인 4월15일은 수요일이고, 0:일요일이라서 수요일인 3이 출력된다
	startDate.setDate(startDate.getDate() - startDate.getDay());
	offset = 7;
} else if (term === 3) {
	startDate.setDate(1);
	offset = (new Date(startDate.getFullYear(), startDate.getMonth() + 1, 0)).getDate();
}

https://joshua1988.github.io/web-development/javascript/promise-for-beginners/

 

자바스크립트 Promise 쉽게 이해하기

(중급) 자바스크립트 입문자를 위한 Promise 설명. 쉽게 알아보는 자바스크립트 Promise 개념, 사용법, 예제 코드. 예제로 알아보는 then(), catch() 활용법

joshua1988.github.io

 

이런 글을 쓸 수 있는 개발자가 되고 싶다...

 

 

/* eslint-disable no-console */
/* eslint no-constant-condition: "error" */
const a = 1;
console.log(a);

const obj = {
	sayNode () {
		console.log('node');
	},
	sayJs: 'sayJs',
	['es' + 6]: 'fantastic',
};

obj.sayNode();
console.log('sfsdfds');

const example1 = (x, y) => { return x + y; };
 
const candyMachine = {
	status: {
		count: 0,
		name: 'node',
	},
	getCandy () {
		this.status.count--;
		return this.status.count;
	},
};

const condition = true;
const promise = new Promise((resolve, reject) => {
	if (condition) {
		resolve('성공');
	}
});

promise.then((message) => {
	console.log(message);
});

const plus = (a, b, callback) => {
	sum = a + b;
	callback(sum);
};

plus(1, 2, (result) => {
	console.log(result);
});

console.log('종료');

const funcA = () => {
	console.log('a is created.');
};

const cA = funcA;

cA();

let funcB = (callback) => {
	callback();
};

funcB(cA);

funcB = (str) => {
	console.log('`str`is created');
};

funcB('a');

function func () {
	function cb () {
		console.log('리턴된 함수 실행');
	}
	return cb;
}
func(); // 값 : func함수 안에 있는 cb함수
func()(); // 출력 : 리턴된 함수 실행

const myCb = func(); // myCb 변수에 func() 값인 cb함수를 전달한다.
console.log(typeof (myCb)); // 출력 : function
myCb(); // 출력 : 리턴된 함수 실행

/*
https://joshua1988.github.io/web-development/javascript/javascript-asynchronous-operation/
엄청 잘 설명되어있음.  
즉, 함수로만 get함수가 원래 response 받아서 안에서 출력하는 애였는데 출력전에 
자스가 함수형이라서 함수 껍데기들만 바로바로 실행하다가 바깥의 콘솔호출을 해버리면 아직 안채워졌으니 undifined뜨지.
이럴때 <내가 하려는게 결과를 콘솔호출이니까 콘솔호출 로직을 파라미터부분에 함수로 넣고 그 함수에 결과를 인자로 하도록 정의해서 안에 함수 실행문을 정의하면
결과가 나왔을 때만 호출되서 나온다. >근데 그럼 안에 안에 안에되니까 복잡해지니까 패턴으로만이라도 분리를 할 수 있다는거고
실질적으로 분리하려면 promise 나 async를 사용하는 것이다 .
참고로, 콜백을 밖에서 따로 정의해도 되지만 본함수 그대로 호출하면서 파라미터에서 함수를 정의해줘도 된다! (그게 promise포스팅의 첫번째 예제 코드임)
자스는 파라미터의 형태도, 갯수도 세지않고 들어오면 알아서 넣고 함수 실행이 된다. 
자스는 파라미터를 변수뿐만이 아니라 함수도 받기 때문에 정의도 안한 함수 이름 써놓으면 그게 매개변수고,
함수로 쓸거면 그 안에서 이름()꼴로 호출해도 되는거임,.

다만, promise에선 그게 resolve와 reject인거고 그게 쓰이는 내용으로 함수내용이 정의되면 fullfilled상태가 되는거고 then과 catch를 쓸 수 있는거다.
resolve 파라미터에 정의된게 결과값으로 저장되고 그 값을 then에서 쓸 수 있다. 
즉, 프로미스가 나온 이유는 비동기 할 일보단 안할 일이 많은데 자꾸 비동기로 처리하니까 콜백을 쓰고, 콜백이 자꾸 중첩되게 하는데
콜백은 결국 인자가 결과가 잘나왔고 못나왔고 두가지 경우로 나뉘니까 잘나온거에 대한 처리 then과 아닌 경우 catch로 나눠서 밖에서
패턴분리해서 쓸 수 있게 만드는거다.
*/

// 내가 쓴 예제~~
let val = 1;
function testCallback (callback1) {
	let x;
	let y;
	if (val === 1) {
		x = 1;
		y = 1;
	} else {
		x = 2;
		y = 2;
	}
	return callback1(x, y);
}

const res = testCallback((tx, ty) => {
	console.log(tx + ty);
	return tx + ty;
});
console.log('res is ' + res);

val = 2;
function testPromise () {
	return new Promise(function (resolve, reject) {
		let x, y;
		if (val === 1) {
			x = 1;
			y = 1;
		} else {
			x = 2;
			y = 2;
		}
		resolve(x + y);
	});
}
console.log('after 3 step is ');
testPromise().then(firstfunc).then(secondfucn).then(thirdfunc); /* promise 객체는 resolve는 값만 넘겨주고 반환값은 없으므로 호출은 마지막 단계 함수 안에서 해결해야한다 . 혹은 반환을 따로 하던가 */

function firstfunc (res) {
	return new Promise(function (resolve) {
		resolve(res + 10);
		return res + 10;
	});
}

function secondfucn (res) {
	return new Promise(function (resolve) {
		resolve(res + 10);
		return res + 10;
	}); 	// 실행문이니까 세미콜론 붙여야 됨
}

function thirdfunc (res) {
	console.log(res + 10);
	return res + 10;
}

// 위의 예제들을 async를 써서 코드를 줄여보자.
async function testAsync (tmp1) {
	let res4 = await firstfunc(tmp1);
	res4 = await secondfucn(res4);
	res4 = await thirdfunc(res4);
	console.log('r u ok?' + res4);
}
testAsync(1);

/*
참고로 resolve는 따로 반환하지는 않고 다음 then의 인자로 전달할 수 만 있게 해주는 애고
반환값으로 쓰고싶으면 return 해야함
*/

 

이 아래 코드는 콜백부분, 프로미스부분, async 부분으로 주석처리된거 부분별로 풀어서 돌려봐야됨. 

주석 다 풀고 동시에 돌리면 순서 섞여서 나오기 때문에 내가 promise로 만든게 1-2-3의 순서로 되는지 확인을 못함

/* eslint-disable no-console */
const fs = require('fs');
console.log('시작');

/*
fs.readFile('./readme2.txt', (err, data) => {
	if (err) {
		throw err;
	}
	console.log('1번', data.toString());
});

fs.readFile('./readme2.txt', (err, data) => {
	if (err) {
		throw err;
	}
	console.log('2번', data.toString());
});

fs.readFile('./readme2.txt', (err, data) => {
	if (err) {
		throw err;
	}
	console.log('3번', data.toString());
});

console.log('비동기 처리 안된 코드 끝');
*/
// 위는 비동기인데 걍 놔둬서 꼬인거

/*
fs.readFile('./readme2.txt', (err, data) => {
	if (err) {
		throw err;
	}

	console.log('1번', data.toString());
	fs.readFile('./readme2.txt', (err, data) => {
		if (err) {
			throw err;
		}
		console.log('2번', data.toString());
		fs.readFile('./readme2.txt', (err, data) => {
			if (err) {
				throw err;
			}
			console.log('3번', data.toString());
		});
	});
});

console.log('콜백지옥이지만 비동기처리는 된(순서를 맞춘) 끝'); */
// 위는 콜백지옥으로 구현 (함수가 호출되면서 새 함수를 불러서 인자가 들어갔을때만 되도록..)

/*
fs.readFile('./readme2.txt', (err, data) => {
	if (err) {
		throw err;
	}
	const promise = new Promise(function (resolve, reject) {
		resolve(data);
	});
	promise.then(pro1).then(pro2).then(pro3);
});
*/
function pro1 (data) {
	return new Promise(function (resolve, reject) {
		console.log('1번', data);
		resolve(data);
	});
}
function pro2 (data) {
	return new Promise(function (resolve, reject) {
		console.log('2번', data);
		resolve(data);
	});
}
function pro3 (data) {
	return new Promise(function (resolve, reject) {
		console.log('3번', data);
		resolve(data);
	});
}

console.log('promise 처리 끝');
// 위는 promise로 구현 .. util 써서 하는거도 연습해보자 나중에

fs.readFile('./readme2.txt', async (err, data) => {
	if (err) {
		throw err;
	}
	let l = await pro1(data);
	l = await pro2(data);
	l = await pro3(data);
});
console.log('async await 처리 끝'); 
// async await 로 구현

 

 

 

오픈소스란? 소스코드를 공개하여 누구나 수정,배포할 수 있게 만든 소프트웨어

1980년대부터 하드웨어 뿐만이 아니라 소프트웨어에도 저작권이 필요하다는 인식이 생겼다. (빌게이츠 힘씀)

그래서 라이센스가 생겨서 모두 돈주고 쓰게 됐지만 여기에 반감을 가진 사람들이 프리웨어 선언을 함!

 

*프리웨어-공짜가 아니라 수정,재배포가 자유롭게 가능하다는 것

ㄴ리눅스->레드햇,우분투,데비안

ㄴ그 외->안드,크롬,mysql.. : 아, 오픈소스의 정의를 정확히 알게 되니 왜 mysql이 오픈소스라서 써야하는지 알겠군! 안드는 근데 오픈소스라도 수정은 구글만 가능함.

 

 

 

+권한을 사용자에게 더 줄 거냐, 원 저작자에게 더 줄거냐의 문제?

 

원저작자에게...:

GPL  (마음대로 쓸 수는 있지만 수정한 것은 수정한 것도 오픈해야함. 기업이 불리),

LGPL  (LGPL은 less gpl로, 컴파일 된 파일을 호출만 하는거면 공개안해도 된다는거)

 

사용자에게...

MIT,BSD,Apache  (수정한 뒤 오픈하지 않아도 됨. 되도록 이 쪽 라이센스를 쓰자!)

 

+모바일 측면(갑자기 왜 나오는지는 모르겠지만..)

v1~v3.0/v3.1~v5.0/v5.1~

같은 안드로이드라도 이렇게 세가지 다른 os다. 메모리 관리법이 다르기 때문.

초기버전은 지원하려면 3배는 많은 비용이 드는데 아직 동남아는 초기버전 쓰는 곳 많아서

지원범위 정할 때 신중히..! (앱 성공하려면 중국진출을 해야한다..)

중국은 aosp라고 안드중에서도 딴거 다 뺴고 os만 들어있는 os 기반으로 쓴다. 즉

한국의 안드개발자와 중국의 안드개발자 스타일 많이 다르다는 것.

 

~~~모바일에선 사용자가 많아도 수익이 적다.

장비나 오라클 사지도 못하고, 많은 사용자를 어떻게 견디냐?

그 대안으로 백엔드도 오픈소스화 되는거임(아 모바일 때문에 오픈소스가 중요해진거구나..)

~~~

 

 

+백엔드 측면

 

Node.js를 예로 들자. 이 기술의 장점은~

 

->싱글스레드 사용.(여기서 os 공부한게 도움이 되는구나!ㅠㅠ)

원래 user level에서 락킹(멀티스레드에서만 고려)걸고 이런 저런 처리를 하는데 node.js는 커널레벨에서 처리. golang도 즉, cpu가 4개면 스레드 하나만 뜨는게 아니라 cpu갯수만큼 스레드 띄우고

모든걸 비공개로 해서 콜백만 받아서 처리함으로서 개발자의 실수를 줄인다. 

 

->npm(노드를 사용한 라이브러리 집합)이 엄청 커짐. 개발 생산성이 높아짐

 

->논블로킹 I/O

유저레벨의 io작업때문에 다른 유저레벨의 스레드가 기다리는게 아니라 io를 커널에 위임해뒀다가 호출하는 구조임.

 

->node.js의 js는 사실 껍데기고, 그 안의 소스는 사실 c++로 되어있어서 빠르다

 

이렇기 때문에, 어디에 적합하냐면~~

 

->restful api에 적합.

->db에 접속해서 data 가져오는 등 많은 I/O를 처리하는데 적합하다.

->실시간 처리에 강함

 

//여기까지 이해 잘 안가면 운영체제 카테고리의 글들 다시 읽자

 

어디에 부적합하냐면~~

 

->멀티스레드 앱

->큰데이터 연산(게다가 이건 python으로 다하지)

->cpiu 부하걸리는 작업(=> golang이 보완책)

->복잡한 비즈니스 로직(스프링이 건재한 이유. 스프링 클라우드 생기면서...자바가 강하게 지키고 있다)

 

아 이래서, node.js거리는구나! 그리고 각각 맞는 분야가 있으니 무작정 spring 버리자는거도 아님!

 

사용자 늘어날 때 http 반응속도

경사 오진당~~~~

 

 


여기부터 좀 가볍게 적는다!

 

+DB 측면

 

+mongoDB

NoSQL 사용하는 DBMS 종류이다. 

NoSQL은 스키마가 없고, 데이터가 삽입될 때 스키마하 함께 추가되는 것이 특징이다.(자세한 것은 db 카테고리 글)

 

이렇게!!json 자체가 db에 저장된다! 대박..원랜 파싱해서 sql로 바꾸고해야했는뎅

 

 

+json은 텍스트, 바이너리로 바꾼건 bson

 

몽고db,,약간 하둡처럼 master와 여러대의 slave로 아키텍쳐가 이루어져 있다.

하둡도 비정형 데이터 대상이라서 그런가?

 

+오토샤딩 지원!(샤딩은 nodql 글에서 전체 갱신문제 관련)

 

+redis

read의 성능을 어떻게 더 끌어낼 것인가?

 

+이런 분산환경들을 관리하는 오픈소스가 zookeeper,etcd 등이 있음.

 

+클라우드 측면..

사용자 특정 시간에만 늘어나면 그 시간 전에 서버 쉽게 추가하도록 스케줄링 가능. 

글로벌하게 서비스가 성장할 경우(직접 방문해서 다 하는게 아니라 aws 같은 애한테 맡김)

but 공유자원이기 때문에 IOPS 문제 보장 안될 때가 있음. 그러니 그거 보완은 사서 써야함.  많이 비쌈.

 

클라우드 환경에서 고려해야할 것 몇 가지

1.IOPS

2.Disk Queue Length

3.CPU Steal Time

+aws는 1년에 20시간은 장애나도 보장안하니 애저를 하나 더 돌리고 있거나 백업서버 준비해야함

 

클라우드 문제 발생할 가능성 많은데 여기 적진 않을 것. 필요시 찾아보자

오픈스택 캠프 참고

 

클라우드 나오기 전

   

 

스케일업/아웃 비용->하둡 글

이후(기능별로 서버 인스턴스 따로 설치함.=>마이크로 서비스 아키텍쳐 MSA)

 

그래서 서비스가 돌아가면 이런 구조로 돌아간다! 굉장히 복잡...이렇게 큰 구조를 가장 빡세게 쓰는 곳은 현재

넷플릭스. aws에서 모든걸 하고있다. aws에서 로드밸런싱 처리, 특정부하 이상오면 튕기는 서킷브레이크,로그를 처리하는 ELK 스택 등의 일을

처리하는게 스프링 클라우드임. 이래서 아직 자바는 죽지 않은거고..너무 복잡한 서비스는 스프링 쓰는거구나.

 

 

 

 

 

 

 

 

 

 

 

'Skill > ETC' 카테고리의 다른 글

깃허브 필수 내용  (0) 2020.01.22
Hadoop  (0) 2019.11.06

한장으로 알 수 있는 깃허브 (1).pdf
3.41MB

'Skill > ETC' 카테고리의 다른 글

오픈소스 AI 온라인 교육 과정 [공개SW의 이해]  (0) 2020.04.14
Hadoop  (0) 2019.11.06

문제: 잘되던 스프링 프로젝트가 갑자기 main을 찾을 수 없다고 함

원인: spring-jdbc dependency를 추가할 떄 spring-context 앞에 추가를 했기 때문이다. 

context가 가장 먼저 만들어져야 그 다음것들을 만들 수 있기 때문에 순서를 바꾸면 에러가 발생

해결: jdbc 디펜던시를 context 디펜던시 뒤로 보내줬다

Several ports (8005, 8080, 8009) required by Tomcat v7.0 Server at localhost are already in use. The server may already be running in another process, or a system process may be using the port. To start this server you will need to stop the other process or change the port number(s).

 

 

원인: 오라클 서버 프로그램을 켜두면서 톰캣을 실행한 경우 충돌이 나는 경우가 많다.

 

해결법: 

1. server.xml을 찾아서 포트번호를 바꿔준다

2.cmd에서 netstat -ao를 통해 사용중인 프로세스를 kill한다

3.db를 그때 그때 꺼준다

 

나는 3번을 주로 쓴다. 충돌나는 이유가 대부분 오라클 db때문이기 때문에 아예 stop database 실행파일을 바탕화면에 꺼내두었다. 충돌날때마다 한번씩 눌러주면 짱 편하다. 

 

위치: C:\oraclexe\app\oracle\product\11.2.0\server\bin\ 에 stop DB 실행파일 있다.

 

 

 

이클립스에서 스프링 프로젝트 열기

how to: 프로젝트 파일을 압축해제-> import->maven existing project ->browse->해당 파일 찾기.

+웬만하면 워크스페이스에 파일을 두자! 
(그냥 프로젝트를 오픈시키면 메이븐 라이브러리가 포함되어 있지 않아서 빌드를 못한다)
(스프링과 메이븐이 설치되어있어야 함)

 

깃허브에 스프링 프로젝트 올리기

how to:기존에 만들어둔 repository가 있다면, 그곳에 이름이 같은 파일로 create file 또는 files를 하면 PR(Pull Request)을 생성할 수 있다.  이때 new branch를 체크해서 만들면 해당 PR은 팀원과 상의 후 본 코드에 merge할 수 있다.

+이때, 파일 변화를 볼 수 있는데 ++도 중요하지만 --가 되는 부분에 특히 집중해야한다. 잘못하면 만든 코드가 다 날라갈 수도 있다. merge된 코드(최종코드)에선 history로 들어가면 이전에 존재하던 코드들이 보이고, 어떤 변화가 있었는지 알 수 있고 코드 한줄 한줄에 코멘트도 달 수 있다. 또, 그 코멘트에 대해 사람을 추가하여 토론 또한 가능하다.

 

 

 

느낀점: 형상관리 툴을 처음 사용해봤는데 프로젝트에 없어서는 안될 요소라는 생각이 들었다. 코드가 어디가 어떻게 바뀌었는지 한눈에 볼 수 있고, 작은 이슈도 그냥 지나치지 않고 함께 고민해보고 다양한 관점으로 토론해보는 방식이 협업에 많은 도움이 되었다.  하지만 사용법은 따로 공부하면서 이것저것 만져보면서 익혀야할 것 같다. 

깃: 분산 소스 버전관리 시스템(혼자 할 때 유용)

깃허브:깃을 업로드하는 웹사이트(여럿이서 공동개발할 때 유용)

 

 

+ Recent posts