인스턴스 생성까지 끝낸 후
putty 다운
puttygen 으로 pem 파일을 ppk로 변경
ubuntu@~~~ 로 접속
sudo apt-get update
최신 버전엔 nodejs 와 npm이 포함되어 있다.
sudo apt-get nodejs
sudo apt-get npm
nodejs 설치함
sudo apt-get install mongodb-server mongodb-clients
몽고디비 설치
vim 명령어 모음
http://hyeonstorage.tistory.com/274
nodejs 프로세서 관리 모듈
sudo npm install pm2 -g
앱이 계속 살아있게 도와주고 죽으면 다시 살려줌
sudo pm2 start server.js
서버를 계속 실행시켜줌
pm2 kill
pm2 stop ID
pm2 ps
mv 이름 바꿀이름
도커 관련
https://hiseon.me/2018/02/19/install-docker/
2018년 10월 30일 화요일
Reactjs 정리
리액트
데이터가 props , state로 관리됨props은 부모 객체에서 만들고 자식에게 값을 넘기거나 함수를 등록해두면 자식 쪽에서 함수 실행 가능
값을 전달하거나 자식쪽에서 값을 받을 때 사용 ( 자식쪽에서 props의 값을 수정 못함 )
정적인 것에 사용
props는 태그의 값으로 전달함
state는 사용자에게 보여지는 동적으로 변할 수 있는 값들을 모아둠
변하는 값들을 보여주거나 부모에게 넘김
state는 객체로 만듬
this.setState가 호출되면 리렌더링 됨
정리 1
- 예시index.js에서 reactDOM으로 app.js를 랜더링함
app.js에서 다른 컴포넌트들을 랜더링함 (props로 create함수 등록)
컴포넌트에서 버튼을 눌러 submit할때 함수를 등록
submit 함수에서 부모 props로 데이터 전달 (create함수 사용) this.props.onCreate(this.state)
e.prevenDefault() 하면 submit할때 새로고침 하는걸 막아줌
2018년 10월 29일 월요일
파이썬으로 엑셀 다루기
엑셀을 다루는 라이브러리 인스톨
pip install openpyxl
wb = Workbook()
ws = wb.active
엑셀을 활성화 하고
시트를 활성화함
if file.endswith('.txt') :
f = open(file, 'rt', encoding='utf8')
경로에 있는 파일을 읽음
파일 중에 .txt로 끝나는 파일
파일을 읽음
line = f.readline()
if not line : break
ws['A'+str(c)]=i
c=c+1
wb.save('result.xlsx')
pip install openpyxl
1. 엑셀 활성화
from openpyxl import Workbookwb = Workbook()
ws = wb.active
엑셀을 활성화 하고
시트를 활성화함
2. 폴더에서 파일 읽기
for file in os.listdir('경로') :if file.endswith('.txt') :
f = open(file, 'rt', encoding='utf8')
경로에 있는 파일을 읽음
파일 중에 .txt로 끝나는 파일
파일을 읽음
3. 텍스트 파일에서 한줄씩 읽기
while True :line = f.readline()
if not line : break
4. 읽은 값 엑셀에 작성
for i in 배열 :ws['A'+str(c)]=i
c=c+1
wb.save('result.xlsx')
5. exe 파일로 배포
pyinstaller -F -n excel.exe excel_test.py2018년 10월 27일 토요일
깃 브랜치
다른 사람들과 작업할 때
각각 브랜치로 자신이 작업할 공간을 만든다.
a b c 브랜치를 각각의 사람들이 만든 후
작업을 진행한다.
작업이 끝나면 마스터 브랜치와 병합한다.
병합 하고 마스터 브랜치를 pull 해서 자신이 수정한 부분과 마스터 부분을 합친다.
마스터 브랜치를 push 한다.
git brach a
git checkout a
브랜치 a를 만들어 작업 공간을 a로 옮김
git add .
git commit -m " "
git push origin a
수정한 부분을 커밋하고 원격 저장소에 올림
모든 작업이 끝난후-------------------------------
git merge master
git add .
git commit -m " "
git pull
git push
마스터 브랜치로 옮긴 후 커밋함
마스터 브랜치를 pull하여 현재 자신의 브랜치의 소스코드와 합쳐줌
합친 소스코드를 push 함
각각 브랜치로 자신이 작업할 공간을 만든다.
a b c 브랜치를 각각의 사람들이 만든 후
작업을 진행한다.
작업이 끝나면 마스터 브랜치와 병합한다.
병합 하고 마스터 브랜치를 pull 해서 자신이 수정한 부분과 마스터 부분을 합친다.
마스터 브랜치를 push 한다.
git brach a
git checkout a
브랜치 a를 만들어 작업 공간을 a로 옮김
git add .
git commit -m " "
git push origin a
수정한 부분을 커밋하고 원격 저장소에 올림
모든 작업이 끝난후-------------------------------
git merge master
git add .
git commit -m " "
git pull
git push
마스터 브랜치로 옮긴 후 커밋함
마스터 브랜치를 pull하여 현재 자신의 브랜치의 소스코드와 합쳐줌
합친 소스코드를 push 함
깃 허브에 처음 올리기
1. 초기 설정
git config --global user.email ""
git config --global user.name ""
처음 아이디와 이름 등록해줌
2. 해당 폴더를 로컬에 저장함
git init
git add README.md
git add .
git commit -m "gd"
현재 폴더에 master branch를 생성하고
현재 폴더에 모든 파일을 저장 대상으로 지정함
현재 branch에 저장 및 메세지를 남김
3. 폴더를 깃에 올림
git remote add origin 주소
git push -u origin master
깃 허브에 업데이트함
4. 수정된 값 추가
git add .
git commit -m "gd"
git push
add로 수정한 파일을 staged 상태로 만든다.
현재 brach에 저장
깃에 올림
5. 깃에서 가져오기
git clone
git pull
git stash
새로운 프로젝트를 가져올때 clon
가져온 프로젝트에서 수정된 값을 가져올때 pull
git pull 에서 충돌 날 때 stash
git config --global user.email ""
git config --global user.name ""
처음 아이디와 이름 등록해줌
2. 해당 폴더를 로컬에 저장함
git init
git add README.md
git add .
git commit -m "gd"
현재 폴더에 master branch를 생성하고
현재 폴더에 모든 파일을 저장 대상으로 지정함
현재 branch에 저장 및 메세지를 남김
3. 폴더를 깃에 올림
git remote add origin 주소
git push -u origin master
깃 허브에 업데이트함
4. 수정된 값 추가
git add .
git commit -m "gd"
git push
add로 수정한 파일을 staged 상태로 만든다.
현재 brach에 저장
깃에 올림
5. 깃에서 가져오기
git clone
git pull
git stash
새로운 프로젝트를 가져올때 clon
가져온 프로젝트에서 수정된 값을 가져올때 pull
git pull 에서 충돌 날 때 stash
2018년 10월 26일 금요일
nodejs에서 mongoDB 사용
1. 데이터 저장
data.save(function(err){if(err){
console.error(err);
return;
}
console.log("위치 : "+req.params.location+" 데이터 : "+req.params.data+" insert ");
})
data 스키마를 먼저 만들고 데이터를 넣어줌
스키마.save를 통해 값을 insert
-스키마
String , Number , Boolean , Date 값을 사용할 수 있음
(Date 값은 ISODate 로 들어가기 때문에 값이 이상하게 들어감
date 와 time 을 나눠서 따로따로 들어가는걸로 해결함)
2. 데이터 조회
data.find({},function(err){if(err){
console.error(err);
return;
}
})
{}안에 찾고 싶은 데이터를 입력 ( 공백이면 모든 데이터 조회)
{'name':'dongwon'} 이름이 dongwon인 데이터를 모두 찾음 (하나만 찾고 싶으면 findone)
3. aggregate
DataModel.aggregate([{'$match':{
'date':time.GetToday()
}},{
'$group':{
'_id':'$location',
'avg':{'$avg':'$data'}
}
},{
'$sort':{
'_id':1
}
}],function(err,DATA){
callback(DATA);
})
데이터를 정제할 때 사용함
$match -> 해당 데이터를 찾아줌
$group -> 데이터들을 그룹화 해줌
_id 값에 location 값들로 그룹화 해줌
avg 값에 그룹화 된 data 값의 평균값을 냄
$sort -> 정정렬해줌 (-1은 역순)
2018년 10월 24일 수요일
브루트 포스 알고리즘 (백준 9095번)
브루트 포스
모든 경우의 수를 다 해봄무식한방법 , 메모리 많이 소비, 100% 풀수있음
정수 n을 주어졌을 때 1, 2, 3의 합으로 만들 수 있는 경우의 수?
1. n을 다 1로 더함
2. n-2에서 2를 더함
3. n-3에서 3을 더함
-> n-1, n-2, n-3을 알면 됨
-> 재귀함수로 해결
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
int n = 0;
int T;
Scanner sc = new Scanner(System.in);
T=sc.nextInt();
for(int i=0;i<T;i++) {
n=sc.nextInt();
int c = bru(n);
System.out.println(c);
}
}
static int bru(int n) {
if(n==0)return 1;
int c=0;
c=c+bru(n-1);
if(n>=2)c=c+bru(n-2);
if(n>=3)c=c+bru(n-3);
return c;
}
}
소켓 통신 방식
tcp 연결 3way handshake
서로의 통신을 위한 관문(port)을 확인하고 연결하기 위하여 3번의 요청/응답 후에 연결이 되는 것이다
1. Client에서 Server에 연결 요청을 하기위해 SYN 데이터를 보낸다
.
2. Server에서 해당 포트는 LISTEN 상태에서 SYN 데이터를 받고 SYN_RCV로 상태가 변경된다. 그리고 요청을 정상적으로 받았다는 대답(ACK)와 Client도 포트를 열어달라는 SYN 을 같이 보낸다.
3. Client에서는 SYN+ACK 를 받고 ESTABLISHED로 상태를 변경하고 서버에 요청을 잘 받았다는
ACK 를 전송한다. ACK를 받은 서버는 상태가 ESTABLSHED로 변경된다.
위와 같이 3번의 통신이 정상적으로 이루어지면, 서로의 포트가 ESTABLISHED 되면서 연결이 되게 된다.
tcp 연결 해제 4way handshake
1. 통신을 종료하고자 하는 Client가 서버에게 FIN 패킷을 보내고 자신은 FIN_WAIT_1 상태로 대기한다.
2. FIN 패킷을 받은 서버는 해당 포트를 CLOSE_WAIT으로 바꾸고 잘 받았다는
ACK 를 Client에게 전하고 ACK를 받은 Client는 상태를 FIN_WAIT_2로 변경한다.
그와 동시에 Server에서는 해당 포트에 연결되어 있는 Application에게 Close()를 요청한다.
3. Close() 요청을 받은 Application은 종료 프로세스를 진행시켜 최종적으로
close()가 되고 server는 FIN 패킷을 Client에게 전송 후 자신은 LAST_ACK 로 상태를 바꾼다.
4. FIN_WAIT_2 에서 Server가 연결을 종료했다는 신호를 기다리다가 FIN 을 받으면 받았다는
ACK를 Server에 전송하고 자신은 TIME_WAIT 으로 상태를 바꾼다.
(TIME_WAIT 에서 일정 시간이 지나면 CLOSED 되게 된다.)
최종 ACK를 받은 서버는 자신의 포트도 CLOSED로 닫게 된다
서로의 통신을 위한 관문(port)을 확인하고 연결하기 위하여 3번의 요청/응답 후에 연결이 되는 것이다
1. Client에서 Server에 연결 요청을 하기위해 SYN 데이터를 보낸다
.
2. Server에서 해당 포트는 LISTEN 상태에서 SYN 데이터를 받고 SYN_RCV로 상태가 변경된다. 그리고 요청을 정상적으로 받았다는 대답(ACK)와 Client도 포트를 열어달라는 SYN 을 같이 보낸다.
3. Client에서는 SYN+ACK 를 받고 ESTABLISHED로 상태를 변경하고 서버에 요청을 잘 받았다는
ACK 를 전송한다. ACK를 받은 서버는 상태가 ESTABLSHED로 변경된다.
위와 같이 3번의 통신이 정상적으로 이루어지면, 서로의 포트가 ESTABLISHED 되면서 연결이 되게 된다.
tcp 연결 해제 4way handshake
1. 통신을 종료하고자 하는 Client가 서버에게 FIN 패킷을 보내고 자신은 FIN_WAIT_1 상태로 대기한다.
2. FIN 패킷을 받은 서버는 해당 포트를 CLOSE_WAIT으로 바꾸고 잘 받았다는
ACK 를 Client에게 전하고 ACK를 받은 Client는 상태를 FIN_WAIT_2로 변경한다.
그와 동시에 Server에서는 해당 포트에 연결되어 있는 Application에게 Close()를 요청한다.
3. Close() 요청을 받은 Application은 종료 프로세스를 진행시켜 최종적으로
close()가 되고 server는 FIN 패킷을 Client에게 전송 후 자신은 LAST_ACK 로 상태를 바꾼다.
4. FIN_WAIT_2 에서 Server가 연결을 종료했다는 신호를 기다리다가 FIN 을 받으면 받았다는
ACK를 Server에 전송하고 자신은 TIME_WAIT 으로 상태를 바꾼다.
(TIME_WAIT 에서 일정 시간이 지나면 CLOSED 되게 된다.)
최종 ACK를 받은 서버는 자신의 포트도 CLOSED로 닫게 된다
nodejs socket.io 사용
socket.emit('이벤트 명',{메세지});
현재 연결되어 있는 클라이언트 소켓에 "이벤트명"으로 데이터를 보낸다
socket.on('이벤트 명',function(data){});
현재 연결되어 있는 클라이언트 소켓으로부터 들어오는 '이벤트 명' 데이터를 function(data)에서 처리함
socket.broadcast.emit('이벤트 명', {메세지});
나를 제외한 다른 소켓 클라이언트들에게 이벤트를 보냄
소켓 데이터 바인딩
각 소켓에서 데이터를 바인딩할 수 있음
socket.set('이름','값',function(){});
해당 클라이언트 socket에 이름값으로 값을 저장함
socket.get('이름',값',function(err,value){});
해당 클라이언트 socket에 이름값의 값을 가져온다
socket.del('이름','값',function(err,value){});
해당 클라이언트 socket에 이름값을 지운다.
room 처리 (그룸)
socket.join('룸 이름');
socket.leave('룸 이름');
io.sockets.in('룸 이름').emit('이벤트 명',메세지);
룸에 있는 모든 클라에게 이벤트 명의 이벤트로 메세지 보냄
io.sockets.manager.rooms
모든 룸 리턴
io.sockets.clients('룸 이름');
룸에 있는 클라 리턴
현재 연결되어 있는 클라이언트 소켓에 "이벤트명"으로 데이터를 보낸다
socket.on('이벤트 명',function(data){});
현재 연결되어 있는 클라이언트 소켓으로부터 들어오는 '이벤트 명' 데이터를 function(data)에서 처리함
socket.broadcast.emit('이벤트 명', {메세지});
나를 제외한 다른 소켓 클라이언트들에게 이벤트를 보냄
소켓 데이터 바인딩
각 소켓에서 데이터를 바인딩할 수 있음
socket.set('이름','값',function(){});
해당 클라이언트 socket에 이름값으로 값을 저장함
socket.get('이름',값',function(err,value){});
해당 클라이언트 socket에 이름값의 값을 가져온다
socket.del('이름','값',function(err,value){});
해당 클라이언트 socket에 이름값을 지운다.
room 처리 (그룸)
socket.join('룸 이름');
socket.leave('룸 이름');
io.sockets.in('룸 이름').emit('이벤트 명',메세지);
룸에 있는 모든 클라에게 이벤트 명의 이벤트로 메세지 보냄
io.sockets.manager.rooms
모든 룸 리턴
io.sockets.clients('룸 이름');
룸에 있는 클라 리턴
noSQL
SQL을 사용하지 않아도 DB를 쓸 수 있는 툴
가볍고 분산처리에 용이하다.
변하지않는 데이터, 작은 데이터를 많이 처리할 때 좋음
데이터를 자주 수정하거나, 조인이 필요한 경우는 안 좋음
module.exports ={
insertDB :function(req,res,Member,callback){
var member = new Member();
var sess = req.session;
var member = new Member();
var sess = req.session;
member._id = req.body.email;
member.name = req.body.name;
member.pass = req.body.pass;
member.save(function(err){
if(err){
console.error(err);
return;
}
member.name = req.body.name;
member.pass = req.body.pass;
member.save(function(err){
if(err){
console.error(err);
return;
}
console.log(member +"등록! \n");
})
callback(req.body.name);
},
callback(req.body.name);
},
searchDB:function(req,res,Member,callback){
var mem;
var mem;
Member.findOne({_id:req.body.email},function(err,member){
//console.log(member + "control");
if(err)return err;
else mem = member;
callback(mem);
//console.log(member + "control");
if(err)return err;
else mem = member;
callback(mem);
})
}
}
app.post('/signup', function(req,res){
var call = require('./controlDB');
var call = require('./controlDB');
call.searchDB(req,res,Member,function(mem){
//console.log(t + "main");
if(mem==undefined){
//console.log(t + "main");
if(mem==undefined){
call.insertDB(req,res,Member,function(m){
req.session.name=m;
res.redirect('/');
});
req.session.name=m;
res.redirect('/');
});
}
else res.redirect('/signup');
});
});
else res.redirect('/signup');
});
});
2018년 10월 22일 월요일
자바 http 통신
HttpURLConnection con;
String url;
HttpReq() {
}
HttpReq(String url) throws IOException {
this.url = url;
URL myurl = new URL(url);
con = (HttpURLConnection) myurl.openConnection();
}
void closeServer() {
con.disconnect();
}
public StringBuilder get() throws IOException {
StringBuilder content;
con.setRequestMethod("GET");
try (BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()))) {
String line;
content = new StringBuilder();
while ((line = in.readLine()) != null) {
content.append(line);
content.append(System.lineSeparator());
}
}
System.out.println(content.toString());
return content;
}
public StringBuilder post() throws IOException {
String urlParameters = "name=Jack&occupation=programmer";
StringBuilder content;
byte[] postData = urlParameters.getBytes(StandardCharsets.UTF_8);
con.setDoOutput(true);
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "Java client");
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
try (DataOutputStream wr = new DataOutputStream(con.getOutputStream())) {
wr.write(postData);
}
try (BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()))) {
String line;
content = new StringBuilder();
while ((line = in.readLine()) != null) {
content.append(line);
content.append(System.lineSeparator());
}
}
System.out.println(content.toString());
return content;
}
String url;
HttpReq() {
}
HttpReq(String url) throws IOException {
this.url = url;
URL myurl = new URL(url);
con = (HttpURLConnection) myurl.openConnection();
}
void closeServer() {
con.disconnect();
}
public StringBuilder get() throws IOException {
StringBuilder content;
con.setRequestMethod("GET");
try (BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()))) {
String line;
content = new StringBuilder();
while ((line = in.readLine()) != null) {
content.append(line);
content.append(System.lineSeparator());
}
}
System.out.println(content.toString());
return content;
}
public StringBuilder post() throws IOException {
String urlParameters = "name=Jack&occupation=programmer";
StringBuilder content;
byte[] postData = urlParameters.getBytes(StandardCharsets.UTF_8);
con.setDoOutput(true);
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", "Java client");
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
try (DataOutputStream wr = new DataOutputStream(con.getOutputStream())) {
wr.write(postData);
}
try (BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()))) {
String line;
content = new StringBuilder();
while ((line = in.readLine()) != null) {
content.append(line);
content.append(System.lineSeparator());
}
}
System.out.println(content.toString());
return content;
}
nodejs 특징 정리
nodejs 특징
비동기식
단일쓰레드
이벤트루프
작은 데이터가 많을때 좋음
단일쓰레드라 큰 함수를 다룰때 안좋음
npm이라는 가장큰 라이브러리를 보유
싱글 스레드 -> 콜스텍이 하나
web api -> 싱글스레드에서 처리해 달라고 요청을 보냄
-> 개발자가 건들일수 없는 다른 쓰레드
v8머신 -> 자바스크립트를 컴파일해줌
자바스크립트 런타임
런타임이란 프로그래밍 언어가 돌아가는 환경
자바스크립트의 런타임은 nodejs와 브라우저
작동 원리
콜스텍에서 수행함
자신이 할일이 아닌경우(api) 외부로 던짐
자신이 할일을 함 , api에서 수행(개발자 범위 밖)
자신이 할일을 함, api에서 끝나면 콜백큐에 콜백함수를 던짐
자신이 할일을 함, 이벤트루프가 콜백큐에서 콜백함수 확인
없음 , 이벤트루프가 콜스텍에 일 없는거 보고 콜백함수를 던짐
콜백함수 실행
함수 1
함수 2(web api에 요청)
함수 3 함수 2
함수 4 함수 2 (끝냄)
함수 4 함수 2
함수 4 함수 2 함수 4
함수 2 함수 4
함수 4
싱글 스레드에서 작업을 하다가
필요시 web api에 요청을 보냄
요청을 보내고 싱글 스레드는 자기 할일을 함
web api에서 작업이 끝나면 이벤트 루프에 알리고 콜백함수를 등록
싱글 스레드에 작업이 없으면 이벤트 루프에서 콜백함수를 가져오고 실햄
자바스크립트 특징 정리
exports로 공개한 모듈은 객체 생성하는게아니라 캐시로 저장됨-> 다른 곳에서 다시 사용하면 저장된 값을 불러옴
es6문법
const , let
블럭 내에 생존
const 는 변경 불가
`(백틱)
문자열 템플릿을 묶을때 사용
var string = `${a}는 ${b}입니다.`;
this
모든 새로운운 함수에 자신 객체를 가르킴
a 함수속 b함숭수에서 this를 쓰면 b 객체를 참조함
하지만 () => {} 로 정의하면 b 함수 안에서 this를 쓰면 a함수 객체를 가르킴
(react 문법에서 필요함)
함수는 하나의 객체
객체 내에서 정의 된 함수는 메소드
2018년 10월 21일 일요일
유니온 파인드 알고리즘
유니온 파인드 :
노드를 합치고 부모 노드를 찾음
초기값
parent[] 에 자기 자신을 넣어줌
Ex) parent[1]=1;
부모 찾기
int find(int x){
if(x==parent[x])return x
else {
int p = find(parent[x]);
parent[x]=p;
return p;
}
}
parent 값에 연결된 노드를 입력함 1 - 2 - 3 이 연결되어 있을때 parent[3] 은 1이됨 ( 연결된 노드중 가장 작은 값을 넣음)
합치기
void union(int x,int y){
x=find(x);
y=find(y);
if(x>y)parent[x]=y;
else parent[y]=x;
}
}
노드를 합치고 부모 노드를 찾음
초기값
parent[] 에 자기 자신을 넣어줌
Ex) parent[1]=1;
부모 찾기
int find(int x){
if(x==parent[x])return x
else {
int p = find(parent[x]);
parent[x]=p;
return p;
}
}
parent 값에 연결된 노드를 입력함 1 - 2 - 3 이 연결되어 있을때 parent[3] 은 1이됨 ( 연결된 노드중 가장 작은 값을 넣음)
합치기
void union(int x,int y){
x=find(x);
y=find(y);
if(x>y)parent[x]=y;
else parent[y]=x;
}
}
2018년 10월 20일 토요일
nodejs 모듈 사용하기
main.js
var mo =require("./hi");
hi.js
exports.A=function(){}
module.exports = {
A : fucntion(){}
}
module.exports는 개별 함수가 아닌 객체를 통째로 exports할 때 사용하라고 나와있다
moduel require은 한번만 실행한다.
exports로 공개한 모듈은 객체 생성하는게아니라 캐시로 저장됨
-> 다른 곳에서 다시 사용하면 저장된 값을 불러옴
var mo =require("./hi");
hi.js
exports.A=function(){}
module.exports = {
A : fucntion(){}
}
module.exports는 개별 함수가 아닌 객체를 통째로 exports할 때 사용하라고 나와있다
moduel require은 한번만 실행한다.
exports로 공개한 모듈은 객체 생성하는게아니라 캐시로 저장됨
-> 다른 곳에서 다시 사용하면 저장된 값을 불러옴
nodejs 이메일 보내기
npm install nodemailer
서버
var mail = require('nodemailer');
var smtp = mail.createTransport({
service: 'Gmail',
auth:{
user:'ID',
pass:'PASS
}
})
컨트롤러
var mailoption={
from:'ID',
to:'ID',
subject:'제목',
text:'내용'
}
smtp.sendMail(mailoption,function(err,res){
if(err)console.log(err);
else console.log('send mail');
})
서버
var mail = require('nodemailer');
var smtp = mail.createTransport({
service: 'Gmail',
auth:{
user:'ID',
pass:'PASS
}
})
컨트롤러
var mailoption={
from:'ID',
to:'ID',
subject:'제목',
text:'내용'
}
smtp.sendMail(mailoption,function(err,res){
if(err)console.log(err);
else console.log('send mail');
})
nodejs package.json 사용법
package.json 생성
npm init
pakage.json을 설치해줌
npm init --yes
package.json을 디폴트값으로 초기화 해줌
Dependency 추가하기
npm install package name --save
Dependency에 패키지 추가함
또는 사용하고 싶은 패키지 복사해서 dependencies 에 붙여넣으면 된다.
설치 및 업데이트
npm installdependency에 있는 패키지들을 설치한다.
npm link package name
프로젝트 폴더에서 명령어 실행하면 글로벌 패키지와 연결시켜줌
2018년 10월 19일 금요일
2018년 10월 15일 월요일
javaFx 기본 버튼 핸들러
package application;
import java.net.URL;
import java.util.Random;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
public class SampleController implements Initializable{
@FXML private Button b1;
@FXML private Label m;
// fxml에서 바로 입력한 함수 구현
public void generateRandom(ActionEvent event){
Random rand = new Random();
int myrand = rand.nextInt(50) + 1;
m.setText(Integer.toString(myrand));
}
@Override
public void initialize(URL location, ResourceBundle resources) {
// TODO Auto-generated method stub
m.setText("gkgkgk");
//자바 내에서 이벤트 함수 구현
b1.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent arg0) {
// TODO Auto-generated method stub
handleB1(arg0);
}
});
}
public void handleB1(ActionEvent event) {
System.out.println("asd");;
}
}
이벤트를 등록할때 fxml 에서 2가지 방식이 있음
1. 태그에 onAction 속성으로 함수를 입력하는방식
2. 등록된 controller에서 입력하는는방식
javafx 이벤트 핸들러 작동 방식
출처: http://palpit.tistory.com/744 [palpit's log-b]
import java.net.URL;
import java.util.Random;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
public class SampleController implements Initializable{
@FXML private Button b1;
@FXML private Label m;
// fxml에서 바로 입력한 함수 구현
public void generateRandom(ActionEvent event){
Random rand = new Random();
int myrand = rand.nextInt(50) + 1;
m.setText(Integer.toString(myrand));
}
@Override
public void initialize(URL location, ResourceBundle resources) {
// TODO Auto-generated method stub
m.setText("gkgkgk");
//자바 내에서 이벤트 함수 구현
b1.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent arg0) {
// TODO Auto-generated method stub
handleB1(arg0);
}
});
}
public void handleB1(ActionEvent event) {
System.out.println("asd");;
}
}
이벤트를 등록할때 fxml 에서 2가지 방식이 있음
1. 태그에 onAction 속성으로 함수를 입력하는방식
2. 등록된 controller에서 입력하는는방식
javafx 이벤트 핸들러 작동 방식
위임형 방식이란 컨트롤에서 이벤트가 발생하면, 컨트롤이 직접 처리하지 않고 이벤트 핸들러에게 이벤트 처리를 위임하는 방식입니다. 예를 들어 사용자가 Button을 클릭하면 ActionEvent가 발생하고, Button에 등록된 EventHandler가 ActionEvent를 처리합니다.
EventHandler는 컨트롤에서 이벤트가 발생하면, 자신의 handle() 메소드를 실행시킵니다. handle() 메소드에는 윈도우 닫기, 컨트롤 내용 변경, 다이얼로그 띄우기 등의 다양한 코드를 작성할 수 있습니다.
출처: http://palpit.tistory.com/744 [palpit's log-b]
자바 정리 배열, 다형성
배열
int[] a,b[] -> a는 1차 , b는 2차final int SIZE = arr.length;
-> 상수로 지정해서 for문 돌릴때 .length를 계속 참조하지 않게함
for(int i :arr) {
-> 조회할때만 가능, 배열 원소 값을 바꾸는건 무의미(참조값을 복사해온다)
System.out.println(arr[i]); 배열의 값은 바꿀수있음
}
public static void printArray(int[] arr)
-> static이 없으면 instance 메소드기 때문에 객체 생성 후 메모리 등록하고 실행해야함
person p[] = new person[3]; //배열객체 생성 , person 객체를 생성한게 아님
person ppp[] = new person[] { new person(),new person(),p};
int [] aTeam = new int[] {120,100,90,80};
int [] bTeam = new int[] {100,100,90};
int [] teams[] = new int[2][];
teams[0] = aTeam;
teams[1] = bTeam;
void p( int... a){} -> 가변인자
다형성
저장공간 데이터타입 >= 값의 데이터타입 (상속이 전제조건, 트리구조로 타입의 크기를 결정)동적바인딩
employee eg = new engineer();
eg.getInfo(); => 컴파일시 employee에서, 런타임시 engineer에서 실행
employee eg[] = new engineer[2];
ef[0] = new engineer();
ef[1] = new manager();
=> 배열로도 동적바인딩 가능
매개변수로 부모클래스로 받으면 확장성이 증가함
a개발사가 고객사 프로그램을 관리할때 상위 클래스를 구현함
고객사는 상위클래스를 상속받고 a개발사의 기능을 사용함
자바 정리 가비지 컬랙션 (garbage collection)
참조값은 주소값이 아님
참조값 -> 주소값 -> 실제값 (GC 때문에 주소값이 계속 바뀔 수 있기 때문에 참조값을 가져온다)heap 영역
new(young) new(young) old1. 처음 만들어진 것들 -> 2. 버리면 안될 것들
3. 다 지움
<- 4. 처음 만들어진 것들
5. 버리면 안될 것들
6. 버리면 안될것들 중에
계속 유지되었던 것
1~5 마이너 GC
old가 꽉차면 정리함 메인GC
JVM-------------
메소드 - 스텍 - heap
스테틱 객체1 -> 객체 변수
객체2 -> 객체 변수
str="asd" str2=new String("asd")
(객체 참조값 또는 값 저장) (실제 객체)
stack method heap
쓰레드 당 다른 클레스(실행 될)
스텍 하나 (메모리에 클래스 정보 올림)
stack method heap
쓰레드 당 다른 클레스(실행 될)
스텍 하나 (메모리에 클래스 정보 올림)
(p1 참조값) person 클래스 올림 p1 객체 생성
(p2 참조값) x p2 객체 생성
this (현재 실행시키는
객체의 참조값)
p1.printInfo() 클래스 정보에서 메소드 실행 -> 지역변수 name, age를 찾음 없으면-> this로 현재 객체의 참조값 가져옮
(p2 참조값) x p2 객체 생성
this (현재 실행시키는
객체의 참조값)
p1.printInfo() 클래스 정보에서 메소드 실행 -> 지역변수 name, age를 찾음 없으면-> this로 현재 객체의 참조값 가져옮
(객체 단위로 정리)
자바 정리
자바 타입
primitive (원시) - int, char, boolean, double ...
reference (참조) - 모든 객체
객체
속성 - 상태, 값
행위 - 동작, 기능
OOP
캡슐화 - 정보 은닉, 결합도 낮음
상속 - 코드 재사용, 개발 시간 단축, 개발 비용 절감, 결합도 높음(오버라이딩)
추상화 - 추상클래스, 인터페이스 ( 사용방법, 동작을 약속 )
다형성 - 오버로딩, 동적바인딩(컴파일시 부모, 런타임시 자식)
JVM
메소드 스택 heap
스테틱 객체1 객체1 값
객체2 객체2 값
메소드 - 클래스, 메소드가 실행 될때 정보를 저장
스택 - 실행되는 순서 (메소드, 변수, 객체 등 값 또는 참조값) ( 쓰레드 당 스택 하나)
heap - 객체의 실제 값
GC
heap - 2개의 new , 1개의 old
마이너 GC - new에 있는 객체 값을 지움 ( 필요한 건 다른 new, old에 옮김)
메인 GC - old에 있는 객체 값을 지움
스택에 참조값을 넣고 실행 순서가 되면 참조값으로 주소값을 찾음 주소값으로 실제 값을 찾음 ( garbage collection 때문)
자바 threadpool
갑작스런 스레드 증폭을 막기위함스레드를 제한된 개수만큼 정해 놓고 필요할떄마다 사용함
스레드가 생성,스케줄링,삭제로 인한 cpu메모리 손실을 방지함
불필요하게 많은 스레드가 만들어질수있음
노는 스레드가있을수있음
쓰레드
Thread -> (일꾼) t.start();
runnable -> 나중에 쓰레드가 처리할 객체 (일)
-> mr r = new mr(); //runnable을 상속받음
Thread t = new Thread(r);
t.run();
쓰레드
blocked
start() ↓ run() ↑ run()종료
new -> runnable -> running -> dead
자원동기화
자료구조
set -> 중복x , 순서x , equals 와 hashcode로 검사함list -> 순서 유지 , 중복 허용
map -> key로 관리(키값은 중복x -> 중복되면 덮어씀) , 순서 x , 중복 허용 (전화번호부)
트리셋 -> 원소의 정렬 유지 -> 추출할때 정렬함
링크드리스트 -> 큐, 덱
백터 -> 데이터 동기화하기떄문에 싱글스레드에서는 안좋음
속도
배열 > list > set > map
이지만 데이터가 10000 이상 담지 않는다면 크게 차이가 없음
ArrayList list = new ArrayList();
list.add(100);
list.add("hello");
list.add(0, "hi");
list.remove(0);
list.remove(new Integer(50));
-> 객체를 비교하는게아니라 내용값을 비교해서 삭제
for(int i=0;i<list.size();i++) {
Object o = list.get(i);
System.out.println(o);
}
ArrayList<Integer> -> list(100) -> int 타입의 100을 자동으로 Integer타입으로 포장해줌
-> get(1) -> Integer타입을 자동으로 int 타입으로 풀어줌
기타
입출력, 객체 생성제거 -> 오버헤드가 큼
패키지 -> name space
디폴트 -> 패키지 프라이빗
final -> 상속금지, 변경 X, 오버라이딩 x
final int z; -> 초기값을 지정하지 않은 상수는 생성자에서 설정해줌
inner class -> 종속성, 클래스 은닉
inner class -> 종속성, 클래스 은닉
str = "hello" -> literal pool을 참고해서 hello가 있으면 가져오고 없으면 새로 만듬
str2 = new String("hello") -> 무조건 heap에 새로 만듬
this() - 생성자 실행
this - 현재 객체의 참조값
import - 메모리는 상관없지만 많이하면 느려짐
부모가 예외처리를 안던지면 자식도 못던짐 -> try catch써야함
래퍼런스 변수를 syso로 찍으면 toString()의 값을 가져온다
오버라이딩 -> 접근지정자는 같거나 넓게, 예외는 같거나 좁게
상태값 유지, 구현된 메소드를 지님 -> 추상클래스
인터페이스의 모든 메소드는 public, 변수는 스테틱 파이널
-> 객체의 동일한 동작을 보장한다. (규격)
( 대규모 프로젝트에서 설계할 때, 다형성을 구성할 떄 )
필터 스트림, 프로세싱 스트림 -> 옵션 ( 스트링을 한번에 읽음), 줄바꾸기
래퍼런스 변수를 syso로 찍으면 toString()의 값을 가져온다
오버라이딩 -> 접근지정자는 같거나 넓게, 예외는 같거나 좁게
인터페이스의 모든 메소드는 public, 변수는 스테틱 파이널
-> 객체의 동일한 동작을 보장한다. (규격)
( 대규모 프로젝트에서 설계할 때, 다형성을 구성할 떄 )
inputstream, outputstream
바이트 단위의 입출력 최상위 스트림
노드 스트림 -> 입출력에 직접 연결되는 스트림 (저 수준 -> byte단위로 읽고 씀)필터 스트림, 프로세싱 스트림 -> 옵션 ( 스트링을 한번에 읽음), 줄바꾸기
얼굴인식 CCTV
opencv -
실시간 이미지 프로세싱을 위한 라이브러리 이미지 프로세싱이 편함
cap = cv2.VideoCapture("./video/"+VIDEO_FILE_PATH)
face_cascade = cv2.CascadeClassifier()
face_cascade.load('./data/haarcascade_frontalface_default.xml')
frame = cap.read()
#frame = frame[0:500, 0:400]
#dst = cv2.transpose(frame)
#frame = cv2.flip(dst, 1)
#얼굴인식 영상 처리
# grayframe = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# blur = cv2.GaussianBlur(grayframe,(5,5), 0)
# faces = face_cascade.detectMultiScale(blur, 1.8, 3, 0, (50, 50))
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray,
scaleFactor=1.2,
minNeighbors=5,
minSize=(100, 100),
flags=cv2.CASCADE_SCALE_IMAGE
)
#원본 이미지에 얼굴 인식된 부분 표시
for (x,y,w,h) in faces:
cx = int(x+(w/2))
cy = int(y+(h/2))
cr = int(w/2)
crop_img=frame[y:y+h,x:x+w]
crop_img=cv2.resize(crop_img,(96,96))
cv2.rectangle(frame, (x-10, y-10), (x + w+10, y + h+10), (255, 0, 0), 3, 4, 0)
count = count + 1
filename = str(count)
cv2.imwrite('./Image/'+File_Path_Name+'/'+Today+filename+'.jpg', crop_img, params=[cv2.IMWRITE_JPEG_QUALITY, 100])
anaconda -
데이터 분석에 필요한 오픈소스를 모아놓은 개발 플랫폼
Anaconda란 쉽게 말해 Python 또는 R 프로그램에 있어 필요한 라이브러리 패키지 관리 및 환경 설정등을 쉽게 해주는 도구로 보면 될 것 같다.
tensorflow -
뉴럴네트워크 기계학습을 위한 오픈소스 라이브러리 아나콘다 환경에서 사용 가능
inception -
구글에서 개발한 딥러닝 오픈소스 (tensorflow 기반)학습할 사진을 넣은 폴더별로 라벨링을 한 후 데이터 파일을 만든다.
소스코드가 너무 길다... python으로 만들어짐
근데 생각보다 정확도가 떨어짐...
아마 데이터셋이 많이 부족해서 나타나는 것 같은데 결국 openface로 모델 변경
openface -
opencv기반으로 만들어진 얼굴인식 + 러닝리눅스기반에서만 사용 가능해서 Docker 설치 후 리눅스 환경을으로 만듦 (openface 이미지가있음)
docker로 진행했기 때문에 코드를 보기가 힘들다...
코드는 python으로 되어있음
1달동안 인공지능 CCTV 프로젝트를 진행했다.
파이썬은 해본적이없어서 처음 환경세팅 하는것부터 엄청 오래걸림.
먼저 파이썬 설치하고 opencv를 설치함
그리고 학습을 위해 tensorflow를 설치하려고 하니까 anaconda 환경이 필요하다함
그래서서 anaconda를 깔고 tensorflow 라이브러리를 사용
tensorflow 라이브러리로 만든 inception 모델 사용
inception 모델이 정확도가 많이 떨어짐 (능력 부족으로 코드는 건들지 못함)
openface로 모델 변경 -> 정확도가 올라감
2018년 10월 14일 일요일
자바 자료구조
자바
내부적으로 배열을 이용하는 ArrayList가 훨씬 빠르다. 하지만 데이터의 추가/삭제가 빈번하다면 LinkedList가 훨씬 효과적이다.
set -> 중복x , 순서x , equals 와 hashcode로 검사함
list -> 순서 유지 , 중복 허용
map -> key로 관리(키값은 중복x -> 중복되면 덮어씀) , 순서 x , 중복 허용 (전화번호부)
트리셋 -> 원소의 정렬 유지 -> 추출할때 정렬함
링크드리스트 -> 큐, 덱
백터 -> 데이터 동기화하기떄문에 싱글스레드에서는 안좋음
Comparator -> 사용자 정의 정렬
String[] s = new String[numbers.length];
for(int i = 0; i < numbers.length; i++)
s[i] = String.valueOf(numbers[i]);
Arrays.sort(s, new Comparator<String>(){
@Override
public int compare(String a, String b){
if(a.charAt(0) == b.charAt(0)){
int aa = Integer.parseInt(a+b);
int bb = Integer.parseInt(b+a);
return bb - aa;
}
return b.charAt(0) - a.charAt(0);
}
});
for(int i = 0; i < numbers.length; i++)
s[i] = String.valueOf(numbers[i]);
Arrays.sort(s, new Comparator<String>(){
@Override
public int compare(String a, String b){
if(a.charAt(0) == b.charAt(0)){
int aa = Integer.parseInt(a+b);
int bb = Integer.parseInt(b+a);
return bb - aa;
}
return b.charAt(0) - a.charAt(0);
}
});
정리 해야할 것들
ETL -> 추출, 변환, 적재 (DB에서 사용) extract, transform, load
카프카 -> pub, sub모델의 메세지 큐 분산환경에 특화되어있음
-> publisher는 메세지를 topic을 통해서 카테고리화 한다. 분류된 메세지를 받기를 원하는 receiver는 그 해당 topic을 구독(subscribe)함으로써 메세지를 읽어 올 수 있다.
opencv -> 실시간 이미지 프로세싱을 위한 라이브러리
inception -> 구글에서 개발한 tensorflow 기반의 모델
tensorflow -> 뉴럴네트워크 기계학습을 위한 오픈소스 라이브러리
tensorflow - gpu를 사용하면 속도 10배 이상 빨라짐
docker -> 컨테이너 기반의 오픈소스 가상 플렛폼, 실행환경을 컨테이너로 추상화하고 동일한 인터페이스를 제공
컨테이너는 격리된 공간에 독립적인 프로세스를 실행함, host os와 동일한 부분은 두고 다른
부분만 컨테이너 내에 패키징한다. host os 에서 명령어를 수행한다.
마운트 -> 리눅스에서 물리적 하드웨어 위치와 폴더의 경로를 연결시켜줌
sql light -> 가벼운 DB 프로그램 (앱에서 사용함)
허브,스위치,라우터 (뒤)
라이센스 확인
dp알고리즘 하나의 문제를 한번만 풀고 답을 저장함
큰 문제를 작은 문제로 나누고, 작은 문제의 답을 다시 사용할 수 있게 저장함.
백트레킹 알고리즘 -> 유망하지 않은 노드를 제외하고 다시 부모 노드로 돌아감 -> 시간단축
크루스칼 알고리즘
커널
- 운영체제를 규정 짓는 매우 중요한 부분. 하드웨어의 자원을 자원이 필요한 프로세스에 나눠주고, 프로세스, 메모리 관리 (시스템콜 을 수행하는 부분)
1. 허브
허브는 여러개의 포트가 있고, 그중 한포트로 들어온 패킷을 단순히 들어온 포트를 제외한 모든 포트로
보내주는 역할을 합니다.
허브를 통해 구성된 로컬망의 모든 장비들이 이처럼 모든 패킷을 공유 한다고 생각 하면 됩니다.
당연히 트래픽 부담이 큽니다.
2. 스위치
위 에서 설명한 허브의 동작을 보면 a 라는 장비가 b 라는 장비에게 데이터를 주고자 하지만 c, d, e 도 이를 다
받게 됩니다. 쓸데 없는 일이 일어나 트래픽이 증가 하는 것이지요. 그래서 이런 불필요한 작업을 줄이고자
개선한 방식입니다.
그 방법은 로컬망에 연결된 장비들의 ip 와 mac 주소를 매핑시켜 그 테이블을 가지고 있다가, 목적지에 맞게
보내 주는 것 입니다. 마치 우채국과 같군요.
그래서 스위치는 처음 장비가 접속되면 위 ip와 mac 주소 테이블을 생성 하는 작업을 해야하고, 끊기면, 위 테이블을
지워주는 역할을 해야 합니다. 그 시간이 조금씩 걸리지요.
3. 라우터
스위치만 있으면 로컬망에 연결된 장비들 끼리 네트워크가 구성됩니다.
하지만 로컬망일뿐 외부와 연결이 되지 않습니다.
라우터는 스위치의 기능에 추가해서 네트워크 상의 가장 가까운 곳에 위치한 다른 라우터의
주소도 가지고 있어 이 라우터와 통신이 가능 합니다.
라우터 끼리 통신을 함으로써 로컬망을 벗어 나게 되며 이들의 집합이 인터넷 이라고 생각 하면 됩니다.
라우터가 가지고 있는 스위치의 기능중 ip 와 mac 테이블이 있다고 했는데. 만약 이 라우터에 연결된
한 장비가 데이터를 보내고자 하는 목적지가 이 테이블리스트 중에 없다면 그냥 가장 가까이에 있는
다른 라우터로 패킷을 보냅니다. 이 가까이 있는 다른 라우터와의 통로가 바로 게이터웨이 입니다.
그래서 게이트 웨이는 외부로 연결되는 통로를 개념적으로 말하는 것이고, 이 기능을 담당하는 것이 라우터가 됩니다.
그럼.. 마지막으로 공유기는 무엇 일까요?
네트워크의 개념을 잡을때 공유기의 위치가 참 애매 한데요.
공유기는 라우터 인가요? 라는 질물을 한다면 " 그..그런거 같기도 한데요??" 라고 말 하겠습니다.
공유기는 일반적인 라우터에서 포트수를 줄이고 NAT 이라는 기능을 추가한 것입니다.
NAT ( Network Address Translation ) ... 사설 IP 분배 기능 입니다.
그래서 인터넷 공급 업체에서 공유기를 갖다 줍니다. 자기네들 서버에서 IP 를 하나 할당 받아..그 하나의 IP 를
집에 연결된 여러개의 컴퓨터에 공유 하기 위해서 입니다.
결론적으로 .. NAT 기능과 스위칭 허브기능이 추가된 라우터 = 집에 설치된 공유기 .. 입니다... 써놓고 보니.. 공유기가
정말 이렇게 엄청난 녀석인가? 하는 생각이 듭니다.
피드 구독하기:
글 (Atom)
flutter 기본 개념 1
Scaffold - 화면 뼈대 역할 - 기본적으로 AppBar body floatingActionButton 같은걸 배치해줌 return Scaffold ( appBar : AppBar ( title : const Text ...
-
Introduction Dynamic Programming (DP) is a fundamental concept in computer science and algorithmic problem-solving. It's a technique tha...
-
리액트 데이터가 props , state로 관리됨 props 은 부모 객체에서 만들고 자식에게 값을 넘기거나 함수를 등록해두면 자식 쪽에서 함수 실행 가능 값을 전달하거나 자식쪽에서 값을 받을 때 사용 ( 자식쪽에서 props의 값을 수정 못...
-
1. react navigation method navigate - go to another screen, figures out the action it needs to take to do it goBack - close active scr...