유의미적인 버전 붙이기(semantic versioning), 짧게 줄여 심버(semver)다.
새로운 버전의 소프트웨어를 옮길때 명시
버전 번호는 MAJOR.MINOR.PATCH 형태, 정수 integer로 표시
major번호가 변경되는 것은 하위호환성이 깨진다는 것을 의미
2016년 2월 16일 화요일
2016년 2월 13일 토요일
[책]소프트웨어 작동법 - 검색
원하는 데이터를 찾아내는 기술 - 검색
데이터를 모아둔 것 - 데이터 집합(data collection)
각 집합에 있는 개별 데이터 - 레코드(record)
하나의 레코드는 key에 의해 구분됨
검색
순차검색 - 순서없이 정렬되어 있음, 처음부터 모두 검색
소트(sort) - 데이터 집합을 특정 순서대로 정렬하는 것
선택소트 (selection sort)
1. 가장 작은 값 가져옴
2. 그다음 가장 작은 값 가져옴
퀵소트(quick sort)
* 피봇(pivot) : 목록 중 특정숫자
- 계산량과 처리속도를 줄인것
- 목록중 아무거나 하나 집고 그것을 기준으로 높은것과 낮은거 정렬
[2,10,1,3,7] ->(피봇:3) ->[ 2,1,3,10,7]->
3 을 기준으로 서브목록 1(2,1) 서브목록2(10,7) 생김
->서브목록1 피봇1->[[1,2],3,10,7]-> 서브목록2 피봇10 ->[[1,2],3,[7,10]]-> 정렬 완료
@ 피봇이 이렇게 가운데면 참 좋은데 한쪽으로 쏠리면 과도하게 많이 걸릴수도 있음
@ 일반적으로 레코드 수가 커질수록 퀵소트가 선택소트보다 성능이 좋음
이진검색 (binary search)
여기서 이진이란 (binary)를 뜻하는 것이 아니고 두개중 하나를 뜻한다.
* 찾고자 하는 데이터 48이라는 키를 갖고 있음
* 집합은 정렬되어 있다 가정함
1. 가운데 있는 레코드를 본다 (62) 9개 남음 [1,,,,62]
2. 가운데 있는 레코드를 본다 (23) 5개 남음 [23,,,62]
3. 가운데 있는 레코드를 본다 (47) 3개 남음 [47,48,62]
4. 가운데 있는 레코드를 본다 (48) 이때 48이 아닐경우 값이 없다 리턴
인덱싱
레코드는 실제 어딘가에 존재(메모리 혹은 하드디스크)
고정길이(fixed-size)방식
- 저장공간 낭비가 발생됨
- 성능상(검색 속도) 이득
-> 고정주소일 경우 특정 레코드의 주소를 찾기 쉽다
(길이가 20이고 주소가 1000부터 시작한다 하면 1000->1020->1040의 형태로 찾을수 있다)
가변길이(variable-size)방식
- 데이터의 길이에 맞춰 저장하는 방식
-> 검색할 경우 고정길이가 아니면 모든 레코드를 세는 수 밖에 없음
* 윈도우의 32, 64는 메인메모리 주소크기 (고정길이)
ex> 4개의 음악이 있다고 치면 실제 데이터 파일은 하드디스크에 저장 하고
한개의 제목과 실제 데이터 파일의 주소 값을 가진 키값을 고정길이 형태로 메모리에 저장
인덱스는 레코드 키와 주소로 구성된 테이블(목록)
슬롯(slot)
- 레코드 저장 위치
해싱
해시함수(hash function)를 통해 slot / 노래제목 / 데이터주소 형태로 저장
- 장점: 일일이 검색하지 않아도 해시 함수를 통해 한번에 접근 할 수 있음
- 단점 : 해시 키값이 중복, 즉 충돌이 발생
충돌 발생 시..
1. 다음슬롯에 채움
-> 그럼 해시 검색시 찾는것이 없으면 다음거부터 순차검색.. 다음 자리가 비어있으면
먼 슬롯까지 순차 검색을 하게 될것이고 굉장한 비효율 발생
2. 슬롯을 삭제 할경우 다음 슬롯에 저장된 것은 찾을수 없음
-> 해당 슬롯에 데이터 주소와 슬롯을 제외한 값은 비워둠(묘석)
==> 이러한 이유로 정기적으로 재해시를 해야됨, 그리고 중복이 발생하지 않도록 해시 알고리즘 중요
웹검색
- 구글의 인덱스 크기는 100페타바이트 == 1억기가 바이트
검색엔진은 로봇(robot)이라는 것을 사용한다.
- 사람의 간섭 없이 자동으로 인덱스를 만들어내는 프로그램
순위결과
- 인바운드 링크 : 외부홈페이지에서 내 홈페이지 페이지로 링크들.
이 인바운드 링크를 통해 순위를 매김
링크파밍(link farming)
- 이러한 인바운드 링크를 무료 호스트나 버려진 웹 사이트에 특정사이트 링크를 걸어인바운드 링크수를 고의적으로 늘리는 작업
데이터를 모아둔 것 - 데이터 집합(data collection)
각 집합에 있는 개별 데이터 - 레코드(record)
하나의 레코드는 key에 의해 구분됨
검색
순차검색 - 순서없이 정렬되어 있음, 처음부터 모두 검색
소트(sort) - 데이터 집합을 특정 순서대로 정렬하는 것
선택소트 (selection sort)
1. 가장 작은 값 가져옴
2. 그다음 가장 작은 값 가져옴
퀵소트(quick sort)
* 피봇(pivot) : 목록 중 특정숫자
- 계산량과 처리속도를 줄인것
- 목록중 아무거나 하나 집고 그것을 기준으로 높은것과 낮은거 정렬
[2,10,1,3,7] ->(피봇:3) ->[ 2,1,3,10,7]->
3 을 기준으로 서브목록 1(2,1) 서브목록2(10,7) 생김
->서브목록1 피봇1->[[1,2],3,10,7]-> 서브목록2 피봇10 ->[[1,2],3,[7,10]]-> 정렬 완료
@ 피봇이 이렇게 가운데면 참 좋은데 한쪽으로 쏠리면 과도하게 많이 걸릴수도 있음
@ 일반적으로 레코드 수가 커질수록 퀵소트가 선택소트보다 성능이 좋음
이진검색 (binary search)
여기서 이진이란 (binary)를 뜻하는 것이 아니고 두개중 하나를 뜻한다.
* 찾고자 하는 데이터 48이라는 키를 갖고 있음
* 집합은 정렬되어 있다 가정함
1. 가운데 있는 레코드를 본다 (62) 9개 남음 [1,,,,62]
2. 가운데 있는 레코드를 본다 (23) 5개 남음 [23,,,62]
3. 가운데 있는 레코드를 본다 (47) 3개 남음 [47,48,62]
4. 가운데 있는 레코드를 본다 (48) 이때 48이 아닐경우 값이 없다 리턴
인덱싱
레코드는 실제 어딘가에 존재(메모리 혹은 하드디스크)
고정길이(fixed-size)방식
- 저장공간 낭비가 발생됨
- 성능상(검색 속도) 이득
-> 고정주소일 경우 특정 레코드의 주소를 찾기 쉽다
(길이가 20이고 주소가 1000부터 시작한다 하면 1000->1020->1040의 형태로 찾을수 있다)
가변길이(variable-size)방식
- 데이터의 길이에 맞춰 저장하는 방식
-> 검색할 경우 고정길이가 아니면 모든 레코드를 세는 수 밖에 없음
* 윈도우의 32, 64는 메인메모리 주소크기 (고정길이)
ex> 4개의 음악이 있다고 치면 실제 데이터 파일은 하드디스크에 저장 하고
한개의 제목과 실제 데이터 파일의 주소 값을 가진 키값을 고정길이 형태로 메모리에 저장
인덱스는 레코드 키와 주소로 구성된 테이블(목록)
슬롯(slot)
- 레코드 저장 위치
해싱
해시함수(hash function)를 통해 slot / 노래제목 / 데이터주소 형태로 저장
- 장점: 일일이 검색하지 않아도 해시 함수를 통해 한번에 접근 할 수 있음
- 단점 : 해시 키값이 중복, 즉 충돌이 발생
충돌 발생 시..
1. 다음슬롯에 채움
-> 그럼 해시 검색시 찾는것이 없으면 다음거부터 순차검색.. 다음 자리가 비어있으면
먼 슬롯까지 순차 검색을 하게 될것이고 굉장한 비효율 발생
2. 슬롯을 삭제 할경우 다음 슬롯에 저장된 것은 찾을수 없음
-> 해당 슬롯에 데이터 주소와 슬롯을 제외한 값은 비워둠(묘석)
==> 이러한 이유로 정기적으로 재해시를 해야됨, 그리고 중복이 발생하지 않도록 해시 알고리즘 중요
웹검색
- 구글의 인덱스 크기는 100페타바이트 == 1억기가 바이트
검색엔진은 로봇(robot)이라는 것을 사용한다.
- 사람의 간섭 없이 자동으로 인덱스를 만들어내는 프로그램
순위결과
- 인바운드 링크 : 외부홈페이지에서 내 홈페이지 페이지로 링크들.
이 인바운드 링크를 통해 순위를 매김
링크파밍(link farming)
- 이러한 인바운드 링크를 무료 호스트나 버려진 웹 사이트에 특정사이트 링크를 걸어인바운드 링크수를 고의적으로 늘리는 작업
2016년 2월 12일 금요일
커맨드 패턴 (command pattern)
커맨드 패턴(Command pattern)이란 요청을 객체의 형태로 캡슐화하여 사용자가 보낸 요청을 나중에 이용할 수 있도록 매서드 이름, 매개변수 등 요청에 필요한 정보를 저장 또는 로깅, 취소할 수 있게 하는 패턴이다.
어떠한 행동에 대한 정의 들을 제어 할때 사용하면 좋다 .
- 명령(command), 수신자(receiver), 발동자(invoker), 클라이언트(client)의 네개의 용어가 항상 따른다.
- 요청과 수행을 분리시켜 느슨한 결합을 유지한다.
- 일련의 행동을 특정 Receiver하고 연결을 통해 캡슐화하고 execute()라는 메소드 하나만 외부에 공개한다.
장점
- 요청부분과 요청실행부분을 분리(낮은 결합도, 독립적 변경 가능)
- 실행취소, 보관, 로그 생성 가능
* 전략패턴(strategy pattern)과 비슷하지만 커맨드 패턴은 전달받은 객체가 하는 일에 대해 정확히 알지 못한다.
- wiki 참조 -
// 자바스크립트로 구현
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="Generator" content="EditPlus®">
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta name="Description" content="">
<title>Document</title>
</head>
<body>
<script>
// 커맨드 패턴
// 리모컨 만들기
// 1. 리시버에서 해당 기능 구현
// 2. command 에 interface 생성
// 3. command에 recevier에서 받은 객체를 실행하는 동작에 대해 execute에 정의
// 4. invoker 에서 setcommand 명령에 대해 저장하는 처리
// 5. invoker에 목적에 맞는 custom메서드를 생성 (ex> 리모컨켜기, 리모컨 끄기 등)
function r(msg){
return function(){
document.body.innerHTML += (msg+"<br />");
}
}
var client, recevier, invoker, command;
function Light(){} //recevier
Light.prototype = {
"on" : r("on"),
"off" : r("off")
};
//(new Light).on();
function lightOnCommand(receiver_obj){ //command
this.execute = function(){
receiver_obj.on();
};
this.undo = function(){
receiver_obj.off();
};
}
function lightOffCommand(receiver_obj){ //command
this.execute = function(){
receiver_obj.off();
};
this.undo = function(){
receiver_obj.on();
};
}
function RemoteControl(){ //invoker
this.setCommand = function(cmd){
this.obj = cmd;
}
this.press = function(){
this.obj.execute();
this.undocommand = this.obj;
}
this.undo = function(){
this.undocommand.undo();
}
}
client = function(){
var light = new Light;
var lightOn = new lightOnCommand(light);
var lightOff = new lightOffCommand(light);
var remoteControl = new RemoteControl;
remoteControl.setCommand(lightOn);
remoteControl.press();
remoteControl.undo();
remoteControl.setCommand(lightOff);
remoteControl.press();
remoteControl.undo();
}();
</script>
</body>
</html>
컴포지트 패턴(Composite pattern) javascript 구현
/*
* 컴포지트 패턴(Composite pattern)이란 객체들의 관계를 트리 구조로 구성하여 부분-전체 계층을 표현하는 패턴으로, 사용자가 단일 객체와 복합 객체 모두 동일하게 다루도록 한다.
* 컴포넌트 : 컴포넌트란 더 큰 프로그램이나 구조물에서 식별 가능한 "일부분"이다, 컴포넌트는 특정 기능이나 관련된 기능들의 조합을 제공한다.
// 보통 트리구조
// 현재 기본 구조 { figure : [rect,line,circle], group: figurelist[] }
// 바꿀 구조 { figure : [rect,line,circle,group]}
*/
function Figure(){
this.shape = "none";
}
Figure.prototype= {
draw : function(){
console.log(this.shape);
}
};
var figure = new Figure();
function Rectangle(){
this.shape = "Rectangle_shape";
};
Rectangle.prototype = figure;
function Circle(){
this.shape = "Circle_shape";
};
Circle.prototype = figure;
function Line(){
this.shape = "Line_shape";
};
Line.prototype = figure;
var rectangle = new Rectangle;
var line = new Line;
var circle = new Circle;
// rectangle.draw();
//각각의 figure를 통합하여 전체 그리기 시도시 이렇게 따로 구현 해야됨
function Group(){
var arr = [];
this.add = function(figure){
arr.push(figure);
};
this.totalDraw = function(){
arr.forEach(function(me, i){
me.draw();
})
};
}
// 상속받는 기능 들에 대해서도 모두 따로 구현해줘야되는 부분을
/* var group = new Group;
group.add(rectangle);
group.add(line);
group.totalDraw();
*/
//구성 공유
function Figure(){
this.shape = "none";
this.arr = []; //배열에 부분들 추가
}
Figure.prototype.add = function(figure){
this.arr.push(figure);
};
function Group(){
this.draw = function(){
this.arr.forEach(function(me, i){
me.draw();
})
};
}
//같은 figure상속
Group.prototype = figure;
var group = new Group;
group.add(rectangle);
group.add(line);
//group 이어도 똑같은 draw메소드
group.draw();
var rectangle = new Rectangle;
//다른 draw도 정상적인 기능
circle.draw();
// 객체와 객체 그룹간 동일한 인터페이스로 사용 가능
2016년 2월 11일 목요일
라라벨 tinker
- tinker라는 뜻은 어설프게 고치다 라는 뜻, 테스트 해보고 연습해보기 편함
1. php artisan tinker
>>> DB::insert('insert into posts(title, body) values(?, ?)', ['Second Title', 'Second Body']);
=> true
>>> $post = DB::selectOne('select * from posts where id = ?', [1]);
>>> DB::update('update posts set title="Modified Title" where id = ?', [1]);
=> 1
1. php artisan tinker
>>> DB::insert('insert into posts(title, body) values(?, ?)', ['Second Title', 'Second Body']);
=> true
>>> $post = DB::selectOne('select * from posts where id = ?', [1]);
>>> DB::update('update posts set title="Modified Title" where id = ?', [1]);
=> 1
라라벨 - 데이터베이스 마이그레이션
데이터 베이스를 만들자 (migration)
1. php artisan make:migration create_posts_table
2. 테이블 스키마 작성
class CreatePostsTable extends Migration
{
public function up()
{
Schema::create('posts', function($table) {
$table->increments('id'); // id INT AUTO_INCREMENT PRIMARY KEY
$table->string('title', 100); // title VARCHAR(100)
$table->text('body'); // body TEXT
$table->timestamps(); // created_at TIMESTAMP, updated_at TIMESTAMP
});
}
public function down()
{
Schema::dropIfExists('posts'); // DROP TABLE posts
}
}
3. php artisan migrate
1. php artisan make:migration create_posts_table
2. 테이블 스키마 작성
class CreatePostsTable extends Migration
{
public function up()
{
Schema::create('posts', function($table) {
$table->increments('id'); // id INT AUTO_INCREMENT PRIMARY KEY
$table->string('title', 100); // title VARCHAR(100)
$table->text('body'); // body TEXT
$table->timestamps(); // created_at TIMESTAMP, updated_at TIMESTAMP
});
}
public function down()
{
Schema::dropIfExists('posts'); // DROP TABLE posts
}
}
3. php artisan migrate
2016년 2월 10일 수요일
classic asp select case 문법 활용
<%
'classic asp select case statement
' 보기싫은 or절 개선 가능
function exp1()
exp1 = ""
end function
function exp2()
exp2 = false
end function
function exp3()
exp3 = true
end function
select case true
case exp1(), exp2()
response.write "exp1,exp2"
case exp3()
response.write "exp3"
case else
response.write "exp4"
end select
'result : exp3
%>
피드 구독하기:
글 (Atom)
