12월 20, 2016

[EC++ 15] Provide access to raw resources in resource managing classes.


resource leak 방지는 well-designed system의 필수 요소 중 하나이다. 이런 목적으로 resource 관리에 RAII class가 사용되지만, 때로는 resource에 직접 접근할 수 있는 방법이 필요하다. 많은 API가 자신의 parameter로 resource를 받아 이에 직접적으로 접근하기 때문에, 이런 API를 활용하기 위해 RAII class는 자신이 관리하는 resource에 직접 접근할 수 있는 수단을 제공해야 한다. 이러한 접근 수단에는 explicit, implicit 두가지 방식이 있다.

  • explicit
    •  get()  method 제공
  • implicit
    • overloaded derefencing operator( -> ),  * ) 사용
    • overloaded type conversion operator 사용

단, implicit conversion은 편리한 반면 오류의 원인이 되기도 하므로 신중하게 사용해야 한다. 아래의 프로그래밍 의도는 Font 객체의 복사였지만, 실제로는 f1이 FontHandle로 형변환 된 후 이것이 복사된다. font handle은 원래 Font class를 통해 관리되고 접근 가능해야 하지만, 실행 결과 이를 관리하는 RAII 객체를 통하지 않고도 직접적으로 접근이 가능해졌다.



Conclusion

RAII class가 explicit conversion과 implicit conversion 등 어떤 access 방법을 제공할지는 해당 RAII class가 수행하는 작업과 RAII class가 사용되는 상황에 따라 달라진다. 가장 좋은 design 방법은 interface을 올바르게 사용하기 쉽고 잘못 사용하기는 어렵게 만드는 것이다.

RAII class 내부의 raw resource를 반환하는 메소드를 제공하는 것은 C++의 encapsulation 원칙을 어겨 C++의 원칙과 모순되는 것처럼 보인다. 그러나 RAII class의 목적은 raw resource의 관리이지 encapsulation이 아니다. 뿐만 아니라  std::shared_ptr 과 같은 RAII class는 true encapsulation으로 구현되어, underlying resource의 loose encapsulation과 결합하여 결과적으로 더 강한 encapsulation을 제공한다.



Summary

  • APIs often require access to raw resources, so each RAII class should offer a way to get at the resource it anages.
  • Access may be via explicit conversion or implicit conversion. In general, explicit conversion is safer, but implicit conversion is more convenient for clients.

Reference

  • Effective C++ by Scott Meyers

12월 13, 2016

[EC++ 14] Think carefully about copying behavior in resource-managing classes.


Synopsis

mutex를 사용하는 경우,  lock(..)  unlock(..) 을 매 번 잊지 말아야 한다. 이를 해결하기 위해 RAII(Resource Acquisition Is Initialization) class의 사용을 고려해 볼 수 있다.



RAII object의 copy behavior 정의

  • Prohibit copy
  • RAII 객체의 copy operation을 허용하지 않아야 하는 경우가 많이 있다. 예를 들어 underlying resource가  std::mutex 인 경우 copy operation은 의미가 없을 뿐 아니라, 잘못된 동작을 초래할 것이다.

  • Reference-count the underlying resource
  • 동일한 객체가 여러번 사용되는 경우, 마지막 사용이 끝난 시점에서 resource가 release 되어야 한다. 이런 경우 적합한 방식이 reference-counting 방식으로,  std::shared_ptr 와 같은 구현 예가 있다.

    만약 자신의 RAII class에 reference counting 방식을 도입하고 싶다면 referece counting을 직접 구현하지 않고,  std::shared_ptr 을 멤버 필드로 정의하여 같은 효과를 볼 수 있다. Synopsis의 Lock class를 이러한 방식으로 구현할 수 있는데, 이 경우 RAII class의 Reference-count가 0이 되어도 mutex가 destruct되어선 안된다. 이 구현은  std::shared_ptr 의 deleter를 지정하여 해결할 수 있다.

  • Copy the underlying resource
  • Resource-managing class를 사용하는 이유가 오직, heap 메모리의 자동 해제 뿐인 경우, 동일한 resource의 카피를 여러 개 보유할 수도 있다. 이런 경우 resource-managing class의 copy operation은 해당 객체의 underlying resource를 deep-copy 해야 한다.

  • Transfer ownership of the underlying resource
  • copy behavior가 해당 객체의 underlying resource의 ownership을 이양하는 경우를 생각해 볼 수 있다. 이러한 구현의 예로  std::unique_ptr 가 있다.



Summary

  • Copying an RAII object entails copying the resource it manages, so the copying behavior of the resource determines the copying behavior of the RAII object.
  • Common RAII class copying behaviors are disallowing copying and performing reference counting, but other behaviors are possible.

Reference

  • Effective C++ by Scott Meyers

12월 12, 2016

SQL DML(Data Manipulation Language) tag:


SELECT

  • Syntax
  • SELECT [table.]attrib1, [table.]attrib2, ...
    FROM table1, table2, ...
    [WHERE search_condition]
    [GROUP BY attrib1, attrib2, ...]
    [HAVING search_condition]
    [ORDER BY order_expression[ASC|DESC]];
  • 조건 연산자
    • 비교연산자 : =, =>, =<, >, <, IN 등

    • 논리연산자 : AND, OR, NOT 등

    • LIKE연산자 : *(%), ?(_), # 등의 기호를 사용해 문자열을 검색

    • BETWEEN : 특정 값의 사이에 있는 튜플을 검색

  • group funtions :  WHERE  SELECT 와 함께 사용되어 표시할 튜플을 선택하는 기준이 된다면,  HAVING  GROUP BY 와 함께 사용되어 그룹을 묶는 기준이 된다. 하나의 그룹을 모집합으로 사용되는 함수로, 일반적으로  HAVING  절과 함께 사용되어 그룹에 대한 조건을 지정한다.
    •  COUNT(attrib 그룹별 튜플의 수를 구한다
    •  MAX(attrib 그룹별 최대값을 구한다
    •  MIN(attrib 그룹별 최소값을 구한다
    •  SUM(attrib 그룹별 합계를 구한다
    •  AVG(attrib 그룹별 평균을 구한다

INSERT

  • Syntax
  • INSERT INTO table_name(attrib1, attrib2, ...)
    VALUES(value1, value2, ...);
  • 테이블의 모든 속성 값을 입력하는 경우에는 table_name 뒤의 속성명을 생략할 수 있다.
  •  SELECT  문을 사용하여 추출한 검색 결과를 삽입할 수도 있다.

DELETE

  • Syntax
  • DELETE FROM table_name
    WHERE condition;
  •  WHERE  절을 생략하는 경우 해당 테이블의 모든 튜플이 삭제된다.

UPDATE

  • Syntax
  • UPDATE table_name
    SET attrib1=value1, attrib2=value2, ...
    WHERE condition;

reference

12월 07, 2016

\b의 용도


 \b

 \b 는 back space를 의미하는 escape sequence로,  \n 과 같이 다음 출력의 위치를 바꿔주는 역할을 한다.  \n 는 다음 출력의 위치를 다음 줄로 바꿔주는데,  \b 는 다음 출력의 위치를 이전으로 한칸 이동(back space) 한다. 아래 예를 참고하자.

cout << "asdf";    // (1) asdf
cout << "1234";   // (2) asdf1234

(1)이 실행되면 콘솔에서 asdf가 출력된다. 출력을 계속하면 다음에 출력할 문자는 f 뒤부터 출력이 되는데, 이는 콘솔 상에서 마지막 출력의 다음 위치를 cursor가 가르키고 있다가 출력이 재개되면 cursor의 위치부터 출력을 계속하기 때문이다. 만약 되돌려진 커서의 위치에 기존 출력의 내용이 있다면 기존의 출력을 새로운 출력으로 덮어쓰게 된다.

// _ (underline)은 커서의 위치
cout << "asdf";    // (3) asdf_
cout << '\b';        // (4) asdf
cout << "1234";   // (5) asd1234_

이를 응용해 이미 출력된 내용을 지울 수도 있다.

// \b로 커서를 하나 되돌린 후 ' '(공백)을 출력해서 기존 출력을 지운 후, 다시 커서를 되돌림
cout << "asdf";    // (6) asdf_
cout << "\b \b";    // (7) asd_

reference

12월 03, 2016

Regular expression 정규 표현식


Regular expression이란?

정규표현식 혹은 정규식이라고도 부른다. Regular expression(regex or regexp)은 특정한 규칙을 가진 문자열을 표현하는데 사용하는 형식 언어이다. regex는 VIM, EMACS 등 많은 텍스트 편집기와 다양한 프로그래밍 언어에서 문자열의 검색과 치환을 위해 지원하고 있다.

regex 문법은 편집기 별로, 프로그래밍 언어별로 전체적으로는 비슷하지만 조금씩 다른 부분이 있기 때문에, 사용 시에는 이런 부분에 유의하며 사용해야 한다.


요소

  • abc...   letters
  • 123...   digits
  • \d   any digits
  • \D   any non-digit character
  • .   Any character
  • \.   period
  • [abc]   only a, b, or c
  • [^abc]   not a, b, nor c
  • [a-z]   chracters a to z
  • [0-9]   numbers 0 to 9
  • \w   any alphanumeric character
  • \W   any non-alphanumeric character
  • {m}   m repetitions
  • {m, n}   m to n repetitions
  • *   zero or more repetitions
  • +   one or more repetitions
  • ?   optional character
  • \s   any white space
  • \S   any non-white space
  • ^...$   starts and ends
  • (...)   capture group
  • (a(bc))   capture sub-group
  • (.*)   capture all
  • (abc|def)   matches abc or def


reference

11월 29, 2016

rdbuf() : 서로 다른 두 스트림을 연결


std::ios::rdbuf()

일부 derived stream class(stringstream or fstream 등)는 객체 생성 시에 associated 된 internal stream buffer를 가진다. rdbuf는 stream의 associated stream buffer를 변경하는 함수로, stream buffer 자체에는 아무련 영향을 주지 않는다.

cin/ifstream, 혹은 cout/ofstream 등, 서로 다른 두 stream을 한 스트림에서 다른 스트림으로 리디렉시키는데 사용한다. 예를 들어 어떤 프로그램에서 input을 console과 cin을 통해 입력받는데, input을 입력받는 코드 부분을 수정하지 않고 file stream을 통해서 입력을 받도록 프로그램을 수정하고 싶을 때 유용하게 사용할 수 있다.

(1) streambuf* rdbuf() const;
(2) streambuf* rdbuf(streambuf* sb);

(1) accessor. 현재 stream의 associated streambuf의 포인터를 리턴.

(2) mutator. 현재 stream의 associated streambuf를 sb로 바꾸고 stream의 error state flags를 초기화. 이전 associated streambuf의 포인터를 리턴.


예제




reference

11월 25, 2016

SQL(Structured Query Language) 종류


SQL이란

RDBMS(Relational DataBase Management System)을 관리하기 위해 설계된 특수한 목적의 프로그래밍 언어로 데이터베이스로부터 정보를 얻거나 갱신하기 위한 표준 대화형 프로그래밍 언어. RDBMS에서 데이터베이스 스키마 생성과 수정, 자료 검색과 관리, 데이터베이스 객체 접근 권한 관리나 트랜잭션 관리 등을 위해 고안됨. DDL, DML, DCL 과 같이 세분화할 수 있음.


DDL(Data Definition Language)

SQL에서 RDBMS의 '구조'를 정의하는 언어 요소. 테이블 생성과 삭제, 변경 등을 담당.

  • CREATE
  • DROP
  • ALTER

DML(Data Manipulation Language)

SQL에서 '데이터 조작'을 위한 언어 요소. 데이터 검색, 등록, 삭제, 갱신을 담당.

  • INSERT INTO
  • SELECT .. FROM ..
  • DELETE FROM ..
  • UPDATE .. SET ..

DCL(Data Control Language)

SQL에서 데이터에 대한 액세스를 제어하기 위한 언어 요소. 권한의 부여, 박탈 등을 담당.

  • GRANT
  • REVOKE
  • SET TRANSACTION
  • BEGIN
  • COMMIT
  • ROLLBACK
  • SAVEPOINT
  • LOCK

Cursor

SELECT statment 실행 결과를 하나의 row 씩 처리하기 위해 서버 측의 result set과 row 획득 위치를 나타내는 개념을 의미. 주로 어플리케이션 등에서 SQL 검색을 실행 후 결과를 처리하기 위해 사용.


reference

SQL(Structured Query Language) 종류


SQL이란

RDBMS(Relational DataBase Management System)을 관리하기 위해 설계된 특수한 목적의 프로그래밍 언어로 데이터베이스로부터 정보를 얻거나 갱신하기 위한 표준 대화형 프로그래밍 언어. RDBMS에서 데이터베이스 스키마 생성과 수정, 자료 검색과 관리, 데이터베이스 객체 접근 권한 관리나 트랜잭션 관리 등을 위해 고안됨. DDL, DML, DCL 과 같이 세분화할 수 있음.


DDL(Data Definition Language)

SQL에서 RDBMS의 '구조'를 정의하는 언어 요소. 테이블 생성과 삭제, 변경 등을 담당.

  • CREATE
  • DROP
  • ALTER

DML(Data Manipulation Language)

SQL에서 '데이터 조작'을 위한 언어 요소. 데이터 검색, 등록, 삭제, 갱신을 담당.

  • INSERT INTO
  • SELECT .. FROM ..
  • DELETE FROM ..
  • UPDATE .. SET ..

DCL(Data Control Language)

SQL에서 데이터에 대한 액세스를 제어하기 위한 언어 요소. 권한의 부여, 박탈 등을 담당.

  • GRANT
  • REVOKE
  • SET TRANSACTION
  • BEGIN
  • COMMIT
  • ROLLBACK
  • SAVEPOINT
  • LOCK

Cursor

SELECT statment 실행 결과를 하나의 row 씩 처리하기 위해 서버 측의 result set과 row 획득 위치를 나타내는 개념을 의미. 주로 어플리케이션 등에서 SQL 검색을 실행 후 결과를 처리하기 위해 사용.


reference

11월 21, 2016

2의 보수


보수(complement)란?

각 자리의 숫자의 합이 어느 일정한 수가 되게 하는 수.


1의 보수

binary 에서 원래 수를 반대로 뒤집은 것.

6: 00000110
6에 대한 1의 보수: 11111001

2의 보수

원래 값의 1의 보수를 취한 후 1을 더한 것으로 원래 값의 음수에 해당. 2의 보수는 binary에서 음수를 표현하는 과정에서 도입된 개념. 최상위 비트 하나를 음수를 표현하는 경우 +0(00000000)과 -0(11111111)의 두개의 0이 존재하는 문제가 발생하는데 2의 보수법으로 이런 문제를 피해갈 수 있음.

6: 00000110
-6 (6에 대한 2의 보수): 11111010

Binary subtraction

6 - 3 = 6 + (-3)

00000110 - 00000011 = 00000110 + 11111101 = 00000011


reference

11월 17, 2016

Random Access Iterator


Random-access Iterator?

자신이 가르키고 있는 element과 연관되어 있는 임의의 position에 접근하여 포인터와 같은 functionality 를 제공할 수 있는 iterator. 모든 Random-access iterator 는 bidirectional iterator이며, 어떤 element에도 constant time으로 접근할 수 있음.


Funtionalities of Random-access Iterator

  • Bidirectional Iterator 가 제공하는 모든 기능
  • Arithmetic operator ex) it1+n, n+it1, it1-n, it1-it2
  • Inequality relation operator ex) it1<it2, it2>it1, it1<=it2, it1>=it2
  • Compound assignment operator ex) it1+=n, it1-=n
  • Offset dereference operator ex) it1[n]

reference

Bidirectional Iterator


Bidirectional Iterator

유효한 범위의 sequance of element에서 begin, end 양방향의 element에 모두 access 가능한 iterator. 모든 Bidirectional iterator 는 Forward Iterator.


Funtionalities of Bidirectional Iterator

  • Default/copy/copy-assignment constructible ex) X it1; , X it2(it1); , it2 = it1;
  • In/Equality operator ex) it1==it2, it1!=it2
  • Dereference as R-value ex) *it1, it1->m
  • Dereference as L-value ex) *it1 = t
  • Increment ex) ++it1, it1++
  • Decrement ex) --it1, it1--
  • L-value are swappable ex) swap(it1, it2)

X는 Bidirectional iterator type, m은 가르키는 멤버, t는 iterator가 가르키는 타입의 object.


reference

11월 13, 2016

Monte-Carlo 알고리즘과 MCTS(Monte-Carlo Tree Search)

Monte-Carlo 알고리즘

난수를 사용하여 함수의 값을 확률적으로 계산하는 알고리즘을 부르는 용어. 계산하려는 값이 닫힌 값으로 표현되지 않거나 복잡한 경우, 이를 근사적으로 계산하기 위해 사용된다. Monte-Carlo 알고리즘을 적용해 원의 넓이를 구하는 경우, 원과 원에 내접하는 정사각형을 그리고 정사각형 안에 많은 수의 점을 찍어 점이 원의 내부에 찍힌 확률을 계산하면 원의 넓이를 근사적으로 구할 수 있다. Monte-Carlo 알고리즘은 임의 시행의 횟수를 증가시킬 수록 정확도가 증가한다.


Monte-Carlo Tree Search(MCTS)란?

MCTS는 최선의 선택(optimal decision)을 찾는 방법이다. MCTS는 의사 결정을 위한 체험적 탐색 알고리즘으로 수식을 만들어 해를 찾기가 쉽지 않을 때 주로 사용되는데, 예를 들어 게임에서 최선의 수를 찾기 위한 방법으로 활용할 수 있다. MCTS를 게임에 적용한다면, 게임에서 두는 각각의 수가 노드이고 게임의 전체 과정은 각 수의 연속인 트리로 표현된다. 각 노드에는 승률이 기록되어 있으며, 게임에서 최선의 수를 찾는 과정은 가장 승률이 높은 노드를 찾아가는 것으로 근사될 수 있다. MCTS는 각 노드 별 승률을 계산하고 승률이 높은 노드를 찾아가는 과정이라 할 수 있다.

트리 탐색의 문제점은 자식 노드가 많아지면 탐색에 시간이 굉장히 많이 걸린다는 점이다. 자유도가 높은 게임의 경우 자식 노드(다음에 둘 수 있는 수)가 굉장히 많아져 모든 결과를 살펴보고 노드 별 승률을 계산하는 것이 거의 불가능하다. MCTS는 전체 가능성을 모두 탐색하지 않고 다수의 random simulation을 통해 게임 결과를 구하여 이를 노드의 승률에 적용하는 알고리즘으로, 자유도가 높은 게임에서도 높은 효율성을 보여준다. MCTS 알고리즘은 Selection, Expansion, Simulation, Back propagation 네 가지 단계로 이루어진다.


  1. Selection (선택): 루트 R에서 시작하여 연속되는 자식 노드를 따라 내려가 노드L을 선택한다.
  2. Expansion (확장): 노드L에서 게임이 종료되지 않은 경우, 새로운 자식 노드C를 생성하거나 기존의 자식 노드 중 하나를 노드C로 선정한다.
  3. Simulation (시뮬레이션): 노드C를 대상으로 random playout을 수행한다
  4. Back propagation (역전파): playout의 결과를 노드 C에서 루트 R까지 업데이트한다.



MCTS를 적용하기 위해서는 다음과 같은 3가지 조건을 만족해야 한다고 한다.

  • 게임의 최대/최소 점수값이 있음
  • 게임의 규칙이 정해져 있으며, 게임이 완전 정보 게임이어야 함
  • 게임의 길이가 제한되어 비교적 빨리 게임이 끝나야 함

reference

11월 02, 2016

Visual studio 에서 C++ 프로젝트 작성 시 arguments 주는 방법


프로젝트 속성 > 디버깅 > 명령 인수

에 인수를 넣어준다. 인수는 공백(space or tab)으로 구분되며, 공백이 포함된 문자열을 하나의 인수로 전달 시엔 문자열을 큰 따옴표("")로 감싸준다.


reference

11월 01, 2016

ODBC data source 설정 시 ODBC driver for SQL server ODBC 항목이 나오지 않는 경우 해결 방법


증상

ODBC data source Administrator 에서 새로운 data source 를 만들 때 드라이버 선택 메뉴에서 ODBC driver for SQL Server 항목이 나타나지 않음.
(SQL Server 등 다른 선택 항목은 존재)


원인

ODBC driver가 설치되지 않았기 때문.


해결 방법

  • Microsoft ODBC driver for SQL Server를 설치
  • SSMS 설치(설치 과정에서 ODBC driver가 함께 설치됨)

reference

  • -

10월 28, 2016

HTTP


HTTP (HyperText Transfer Protocol)

WWW 상에서 정보를 주고 받을 수 있는 프로토콜로 HTML 문서 및 다른 종류의 데이터를 주고 받는데 사용. TCP, UDP 방식을 사용하며 80번 포트를 이용함. 버전 0.9, 버전 1.0 및 버전 1.1이 존재하는데 현재 대부분 버전 1.0 이나 버전 1.1을 사용함. HTTP/2를 개발 중.

HTTP는 클라이언트와 서버 사이의 요청/응답(request/response) 프로토콜로 요청 메시지, 응답 메시지가 각각 구분되어 있으며 이에 따라 공통으로 사용되는 헤더와 request 헤더, response 헤더가 존재함. 먼저 클라이언트가 서버에 연결을 요청하면 Connect, Request, Response, Close 과정을 거쳐 통신을 수행함. 버전 0.9 의 경우 같은 페이지 내에서도 요소마다 Connect와 Close 과정을 거쳐서 효율이 매우 떨어졌지만, 버전 1.0 부터 한번의 Connect 후에 Request와 Response를 반복할 수 있게 됨.


HTTP Request

HTTP Request |devwoodo's blog

HTTP Response

HTTP Response |devwoodo's blog

reference

HTTP Response


내용

HTTP Response 는 HTTP Request 에 대한 응답 패킷. 서버에서 쓰이고 있는 프로토콜 버전, Request에 대한 실행 결과 코드(HTTP Status code), 간략한 실행 결과 설명문(OK 등)이 담겨 있으며, 전달할 데이터 형식, 데이터 길이 등 추가 정보가 MIME 형식으로 표현되어 있음. 그리고 헤더 정보 뒤에는 실제 데이터가 담겨 있음.


HTTP Status code (HTTP Response의 실행 결과 코드)

1XX (조건부 응답)

요청을 받았으며 작업을 계속함을 의미.

2XX (성공)

클라이언트의 요청을 수신하여 이해하고 승낙했으며, 성공적으로 처리했음을 의미

  • 200(Ok)
  • 201(Create)
  • 202(Accepted)
  • 203(Non-Authoritative Information)
  • 204(No Content)
  • 205(Reset Content)
  • ...

3XX (리디렉션 완료)

요청을 마치기 위해 클라이언트가 추가 동작을 취해야 하는 경우


4XX (요청 오류)

클라이언트에 오류가 있는 경우

  • 400(Bad Request) : 서버가 요청의 구문을 인식하지 못함
  • 401(Unauthorized) : 이 요청은 인증이 필요함
  • 403(Forbidden) : 서버가 요청을 거부함
  • 404(Not Found) : 서버가 요청 받은 페이지를 찾을 수 없음
  • 405(Method Not Allowed) : 요청에 지정된 방법을 사용할 수 없음
  • 406(Not Acceptable)
  • 408(Request Timeout) : 서버의 요청대기가 시간을 초과함
  • ...

5XX (서버 오류)

유효한 요청을 서버가 명백히 수행하지 못했음을 의미

  • 500(Internal Server Error) : 서버에 오류 발생해 요청을 수행할 수 없음
  • 501(Not Implemeted) : 서버에 요청을 수행할 수 있는 기능이 없음. ex) 서버가 요청 메소드를 인식하지 못할 때
  • 502(Bad Gateway) : 잘못된 응답을 받음
  • 503(Service Unavailable) : 서버가 오버로드 되거나 유지 보수를 위해 다운됨. 대게 일시적인 상태
  • 504(Gateway Timeout) : 제 때 응답을 받지 못함
  • ...

reference


HTTP Request


크게 GET, POST, 기타 방식이 존재


GET

가장 일반적인 HTTP Request 방식으로 요청 데이터에 대한 인수를 URL을 통해 전송함. URL에 인수가 그대로 나타나기 때문에 보안에 취약한 방식. GET 방식에서는 각 이름과 값을 &로 결함하며 글자수는 255자로 제한됨.


POST

GET과 달리 HTTP 헤더에 데이터를 전송. 내부의 구분자가 각 파라미터(이름, 값 등)를 구분하며, 서버를 이를 해석하며 처리해야하기 때문에 GET 방식보다 상대적으로 처리 속도가 늦음. 많은 양의 데이터를 전송하는 경우 사용.


기타

  • HEAD : 서버 측의 데이터를 요청하고 검색하는데 사용.
  • OPTIONS : 자원에 대한 요구/응답 관계에서 관련된 선택 사항의 정보를 요청할 때 사용.
  • PUT : 메시지에 포함되어 있는 데이터를 지정한 URI에 저장.
  • DELETE : URI에 지정되어 있는 자원을 서버에 지울 수 있게 함.
  • TRACE : 요구 메시지의 최종 수신처까지 루프백 검사에 사용.

reference

10월 21, 2016

Classic RISC pipeline : instruction 실행 순서


5 stage of RISC pipeline

  1. Instruction fetch
  2. The Instruction Cache on these machines had a latency of one cycle, meaning that if the instruction was in the cache, it would be ready on the next clock cycle. During the Instruction Fetch stage, a 32-bit instruction was fetched from the cache.

  3. Instruction decode
  4. Unlike earlier microcoded machines, the first RISC machines had no microcode. Once fetched from the instruction cache, the instruction bits were shifted down the pipeline, so that simple combinational logic in each pipeline stage could produce the control signals for the datapath directly from the instruction bits. As a result, very little decoding is done in the stage traditionally called the decode stage.

  5. Execute
  6. The Execute stage is where the actual computation occurs. Typically this stage consists of an Arithmetic and Logic Unit, and also a bit shifter. It may also include a multiple cycle multiplier and divider.

  7. Memory access
  8. If data memory needs to be accessed, it is done so in this stage.

  9. Write back
  10. During this stage, both single cycle and two cycle instructions write their results into the register file.


reference


const iterator VS const_iterator


  • const iterator
  • const iterator는 iterator를 const로 만듦. iterator는 멤버 필드로 pointer를, 멤버 메소드로 operator++(..), operator+(..) 등의 연산을 가지고 있는 클래스. 이 클래스의 인스턴스에 const를 붙이면 인스턴스 내용을 수정할 수 없게 되므로, 멤버 필드인 pointer를 수정할 수 없게 됨. 즉, const iteratoroperator++(..), operator+ 와 같은 멤버 연산 실행이 불가능. 따라서 container 안에 있는 자료 중 딱 그 하나의 자료만 수정할 때, const iterator를 사용함.

  • const_iterator
  • const_iterator는 클래스 내부의 멤버 필드 pointer가 가르키는 대상의 내용(*pointer)을 수정하는 것을 막기 위해 만든, iterator와는 다른 목적을 가진 클래스. 따라서 const_iteratoroperator++operator+(..) 등 연산을 자유롭게 할 수 있음. container의 자료를 읽기만 가능하게 하려할 때 사용.


요약

  • const iterator : container 안에서 딱 하나의 자료만 수정하려할 때 사용.
  • const_iterator : container 안의 자료들을 읽기 전용으로 불러올 때 사용.

reference

10월 20, 2016

Visual Studio 에서 소스 파일 내 한글 깨짐, 저장 불가 현상


사양

  • Windows10 English -> Korean language pack 설치
  • Visual Studio 2015 community

증상

  • Git에서 remote repos. clone 후 VS에서 열면 소스코드 안의 한글이 모두 깨져서 나옴.
  • VS에서 코드를 작성 시 한글을 사용하면 code page를 949로 변경해야한다는 안내 나오면서 저장이 안됨.

원인

Visual Studio에서 네이티브 프로젝트는 사용자 컴퓨터의 로케일에 맞는 지역 인코딩을 자동으로 설정.


해결방법

  1. Settings(:설정)
  2. 시계, 언어 및 국가별 옵션
  3. 국가 또는 지역
  4. 관리자 옵션 탭
  5. 시스템 로캘을 '한국어'로 변경
cf. 만약 시스템 로캘에 한국어가 뜨지 않으면 시계, 언어 및 국가별 옵션에서 언어 > 언어 추가에 한국어 추가를 시도해 볼 것.

reference

10월 18, 2016

TCP 3-way handshaking, 4-way handshaking

  • SYN : 시퀀스 동기화 요청
  • ACK : 패킷을 받았다는 응답. 다음에 받을 시퀀스 넘버를 가지고 있음.
  • FIN : 연결 종료 요청



3-way handshaking: Connection establishment


  1. Step1
  2. Initiator[CLOSED]가 SYN(To Receiver)를 전송. Initiator는 전송한 SYN(To Receiver)에 대한 ACK를 기다리는 Initiator[SYN-SENT]로 전환.

  3. Step2
  4. Receiver[LISTEN]가 SYN(From Initiator)에 대한 ACK와 SYN(To Initiator)를 전송. SYN(To Initiator)에 대한 ACK를 기다리는 Receiver[SYN-RECEIVED]로 전환. Initiator[SYN-SENT]가 ACK(From Receiver)를 받으면 Initiator[ESTABLISHED]로 전환. 받은 SYN(From Receiver)에 대한 ACK를 전송.

  5. Step3
  6. Receiver[SYN-RECEIVED]가 ACK(From Initiator)를 받으면 Receiver[ESTABLISHED]로 전환. TCP 연결이 확립, 데이터 교환이 가능.



4-way handshaking: Connection termination

세 방향 핸드셰이크는 네트워크로 연결된 미디어를 통해 세 개의 패킷만 전송하면 되지만 이 신뢰성 있는 연결을 종료하려면 네 개의 패킷을 전송해야 합니다. TCP 연결은 데이터가 서로에 관계 없이 각 방향으로 흐를 수 있는 전이중이기 때문에 각 방향으로 개별적으로 전송해야 합니다.


  1. Step1
  2. Terminator[ESTABLISHED]가 FIN(From Terminator)를 전송. FIN(From Terminator)에 대한 ACK를 기다리는 Terminator[FIN-WAIT-1]으로 전환.

  3. Step2
  4. Receiver[ESTABLISHED]가 FIN(From Terminator)에 대한 ACK를 전송. 어플리케이션에게 close 알리고 Receiver[CLOSE-WAIT]로 전환. Terminator[FIN-WAIT-1]은 ACK(From Receiver)를 받으면, FIN(From Receiver)를 기다리는 Terminator[FIN-WAIT-2]로 전환.

  5. Step3
  6. Receiver[CLOSE-WAIT]는 어플리케이션이 close할 준비가 되면 FIN(To Terminator)를 전송. Fin(To Terminator)에 대한 ACK를 기다리는 Receiver[LAST-ACK]로 전환. Terminator[FIN-WAIT-2]는 FIN(From Receiver)를 받으면 ACK를 전송하고, terminating process 전에 전송되었을지 모르는 패킷을 기다리는 Terminator[TIME-WAIT]로 전환. 일정시간 동안 여분의 패킷을 기다린 후 연결 종료 Terminator[CLOSED].

  7. Step4
  8. Receiver[LAST-ACK]는 ACK(From Terminator)를 받으면, 연결을 종료 Receiver[CLOSED].



reference

8월 30, 2016

[EC++ 13] Use objects to manage resources.

Resource 를 object 안에 넣고 이 object의 dtor가 resource를 해제하도록 하여, 사용이 끝난 Resource의 해제를 보장할 수 있다.


auto_ptr

  • Resource를 획득하여 바로 resource-managing objects로 넘김
  • Resource Acquisition Is Initialization(RAII) objects를 사용하여 Resources 를 관리하는 것.
  • Resource-managing objects는 resource의 해제를 보장하기 위해 dtor를 사용

단, auto_ptr 은 소유권을 공유하지 않기 때문에 auto_ptr a에서 auto_ptr b로 복사시 a는 NULL이 되어버림.


Reference-Counting Smart Pointer (RCSP)

배타적인 소유권을 갖는 auto_ptr과 달리 shared_ptr은 소유권을 공유할 수 있다. 클래스가 소유권을 공유하는 객체들의 수를 기록하는 reference counter를 멤버로 가지고 있어서, 소유권을 공유하는 객체들의 숫자가 0이 되면 resource가 해제된다.

단, RCSP는 cycles of references(ex.객체가 서로를 가르키고 있는 경우)에 빠지는 경우 제대로 동작하지 않는다는 단점이 있다.


또 다른 유의점

std::auto_ptr 과 shared_ptr 의 dtor는 (delete[] 가 아니라 delete 를 호출한다. 따라서 이들 객체가 관리하는 resource가 배열인 경우 올바르게 작동하지 않는다. 이런 경우 custom deleter를 지정하여 resource가 적절한 방식으로 해제될 수 있도록 신경써야 한다.


Summary

  • To prevent resource leaks, use RAII objects that acquire resources in their constructors and release them in their destructors.
  • Two commonly useful RAII classes are tr1::shared_ptr and auto_ptr. tr1::shared_ptr is usually the better choice, because its behavior when copied is intuitive. Copying an auto_ptr sets it to null.

Reference

  • Effective C++ by Scott Meyers

8월 25, 2016

[EC++ 12] Copy all parts of an object.

Objective

  • copy all local data member
  • invoke the appropriate copying function in all base classes

잘 정의된 object-oriented system은 copy constructor, copy assignment operator 오직 두가지의 func.을 통해서만 객체 복사를 허용한다. 이 두 함수를 직접 정의하지 않는 경우 컴파일러가 default 함수를 대신 정의해주지만, 필요한 경우 사용자가 두 함수를 직접 정의할 수도 있다. 그러나 이 경우 새로운 data member가 클래스에 추가될 때는 copy funcions에도 반드시 이를 반영해야 한다. 만약 사용자가 실수로 추가된 data member의 복사를 빼놓더라도 컴파일러에선 아무런 경고를 해주지 않는다.

새로운 data member가 클래스에 추가되었을 때
  1. 모든 copying functions update
  2. 모든 ctor update
실수로 update를 하지않더라도 컴파일러는 어떤 경고도 하지 않으므로 주의.
derived class의 copy functions을 구현하는 경우에는 base class 부분도 반드시 고려를 해야한다. 따라서, derived class의 copy functions 안에서 base class의 copy functions을 반드시 호출해줘야 한다.


copy functions 간의 중복 코드 제거

한 copy function에서 다른 copy function을 호출하는 것은 피해야 한다. 특정 상황에서 객체가 오염될 수 있으며 논리적으로도 맞지 않기 때문이다. 꼭 중복 코드를 제거하고 싶다면 copy functions 안에서 공통적으로 호출되는 init(..) 과 같은 별개의 함수를 private으로 정의하는 것이 좋은 방법이다.



Summary

  • Copying functions should be sure to copy all of an object's data members and all of its base class parts.
  • Don't try implement one of the copying functions in terms of the other. Instead, put common functionality in a third function that both call.

Reference

  • Effective C++ by Scott Meyers

8월 24, 2016

[EC++ 11] Handle assignment to self in operator=.

Objective

  1. self-assignment-safe
  2. exception-safe

self-assignment problem

객체가 자기자신에게 assignment를 할 때 self-assignment가 발생. operator= 구현 과정에서 dest. 객체가 유지하고 있던 resource를 해제하고 source. 객체의 resource를 복사한다. 그런데 self-assignment인 경우, dest. 객체와 source. 객체가 동일하다. 따라서 dest. 객체의 resource를 해제하면 source. 객체의 resource 역시 해제되어 아무 것도 남지 않게되서 operation이 의도와 다르게 작동하게되는데, 이를 self-assignment problem이라 한다.

self-assignment problem은 dest. 객체와 source. 객체가 같은 객체인지 비교하는 과정을 삽입함으로써 해소할 수 있다.


exception-safe

assignment operation 과정에서 dest.객체의 resource를 해제한 뒤, 새로운 resource를 (복사)할당 받아 dest.의 resource로 넘겨주는데, 할당 과정에서 exception이 발생할 경우 operation이 의도한대로 작동하지 않을 수 있다. 이런 경우 statement의 순서를 조정하여 exception에 보다 견고한 동시에 self-assignment problem 에서도 안전한 코드를 만들 수 있으며 크게 3가지 방식으로 이를 구현한다.

  • menually ordering statements.
  • "copy and swap" technique
  • variation of "copy and swap" technique

Summary

  • Make sure of operator= is well-behaved when an object is assigned to itself. Techniques include comparing addresses of source and target objects, careful staterment ordering, and copy-and-swap.
  • Make sure that any function operating on more than one object behaves correctly if two or more of the objects are the same.

Reference

  • Effective C++ by Scott Meyers

8월 23, 2016

8월 22, 2016

[EC++ 09] Never call virtual functions during construction or destruction.

  • virtual function 뿐만 아니라 dynamic_casttypeid 같은 language의 RTTI(runtime type information) 파트에서도 Derived object 의 base class construction 중에는 그 object의 타입이 base class 인 것으로 인식.
  • Derived object의 base class member 부분을 초기화하는 동안, 이 객체는 base class 객체인 것으로 인식됨. Derived object 의 derived class member 부분이 초기화 되기 시작한 후에야 이 객체는 derived class 로 인식됨.

  • ctor 내에서 virtual func.을 직접 부르는 것뿐만 아니라, init()과 같은 함수를 통해 간접적으로 부르는 것도 마찬가지 이유로 불가.

해결책

  • 유일한 해결책은 ctor 나 dtor에서 virtual func. 을 부르지 않는 것.
  • 다른 방법으로 해당 func. 을 virtual 대신 일반 func.으로 구현하고, construction 과정에서 필요한 정보를 ctor의 param.로 넘겨주는 방법을 사용.
  • 이 때, param. 를 넘겨주는 helper func.을 (private) static func.으로 구현하면 좋음. func. 을 static으로 구현함으로써 helper func. 내에서 아직 initialize 되지 않은 data member 를 부르는 실수를 막을 수 있음.


Summary

  • Don't call virtual functions during construction or destruction, because such calls will never go to a more derived class than that of the currently executing constructor or destructor.

Reference

  • Effective C++ by Scott Meyers

8월 18, 2016

[EC++ 08] Prevent exceptions from leaving destructors.


C++은 최대 하나의 exception만 처리할 수 있음. 만약 두개 이상의 active exception이 동시에 발생하면 당시의 program 상황에 따라 premature program termination 또는 undefined behavior를 일으킴. dtor가 exception을 처리하지 않고 생략하면, dtor 과정에서 예외가 동시에 발생한 경우 premature program termination이나 undefined behavior를 일으킬 수 있음. dtor가 exception을 생략하는 것은 프로그램 실행 중 언제든 premature program termination이나 undefined behavior가 발생할 수 있어 위험함.

dtor에서 예외를 다루는 방법

  1. Terminate the program
  2. Swallow the exception
  3. Better strategy: 관련된 interface를 따로 정의하여 client가 발생가능한 문제에 대해 직접 대처할 수 있게 함.
  4. ex) DBConn::close() member method와 bool closed member field 를 정의.
    dtor가 수행하던 작업을 non-dtor function에게 이관하여 exception이 dtor에서 발생하는 것을 피할 수 있음. class 의 책임을 client에게 떠넘기는 것이라 볼 수도 있지만, 이런 방법을 통해 client에게 더 넓은 선택권을 제공할 수 있기에 좋은 방법임. client는 operation을 직접 수행하고 예외까지 직접 처리하여 더 안정된 프로그램을 구현할 수도 있고, operation을 dtor에게 맡기는 대신 다소간 프로그램의 불안정성을 감수하는 방법을 선택할 수도 있음.


Summary

  • Destructors should never emit exceptions. If functions called in a destructor may throw, the destructor should catch any exceptions, then swallow them or termainate the program.
  • If class clients need to be able to react to exceptions thrown during an operation, the class should provide a regular (i.e., non-destuctor) function that performs the operation.

Reference

  • Effective C++ by Scott Meyers

8월 08, 2016

char * 타입으로 가르키는 string

char * str = "Hello!"
소스 코드 상에 위와 같이 표현된 string은 string의 내용(character)을 바꿀 수 없음.

위와 같이 표현된 string은 complile time 때 이에 대해 미리 알고 있어야하기 때문에, string이 executable 안에 직접 쓰여짐. Executable 안에 기록된 data는 읽기 전용이기 때문에 수정/변경될 수가 없으며, 수정하고 싶은 data는 executable이 아닌 stack memory나 heap memory에 기록해야 함. 따라서 char str[] = "string" 과 같이 local varialble로 char array를 선언해서 여기에 string을 기록하거나, malloc으로 heap memory 에 공간을 할당하고 여기에 string을 복사해서 사용해야 함.



Reference

7월 18, 2016

[EC++ 07] Declare destructors virtual in polymorphic base classes.

  • Partial destruction problem
  • Base class pointer로 derived 객체를 가르키고 있을 때, 객체가 해제되면 base class의 dtor가 call됨. 이 경우 derived 객체에서 base class 부분의 resource는 해제되지만 derived class의 resource가 해제되지 않아 resource leak 발생하는데, 이를 partial destruction이라고 함.

  • Partial destruction을 막는 방법
  • Base class 의 dtor를 virtual로 선언. 단, 어떤 클래스가 base class 로 쓰이지 않는데도 virtual detruction을 implementation하는 것은 좋지 않음. 클래스에 virtual function이 있는 경우 virtual function을 관리하는 vtbl("virtual table")을 가르키는 vptr("virtual pointer")를 객체가 가지게 되는데, 이 때문에 객체의 크기가 커지게 됨.

  • Destructor call order
  • Derived class의 destructor부터 call되고 base class의 dtor가 마지막에 call됨.


Summary

  • Polymorphic base classes should declare virtual desturctors. If a class has any virtual functions, it should have a virtual destructor.
  • Classes not designed to be base classes or not designed to be used polymorphically should not declare virtual destructors.

Reference

  • Effective C++ by Scott Meyers

7월 14, 2016

[EC++ 06] Explicityly disallow the use of compiler-generated functions you do not want.

  • 방법1. member function을 private으로 선언하고 implementing을 하지 않음.
  • 방법2. member function call을 막는 base class를 생성하고 이를 상속함.
  • 단, 이 경우 multiple inheritance 가 되어 empty base class optimization (Item 40) 같은 몇가지 사소한 문제를 일으킬 수 있음.


Summary

  • To disallow functionality automatically provided by compilers, declare the corresponding member functions private and give no implementations. Using a base class like Uncopyable is one way to do this.

Reference

  • Effective C++ by Scott Meyers

7월 12, 2016

[EC++ 05] Know what functions C++ silently writes and calls.

  1. 사용자가 직접 선언하지 않아도 컴파일러가 자동적으로 정의하는 function이 존재.
  2. copy constructor, copy assignment operator, and destructor 등. 만약 사용자가 constructor를 하나도 직접 선언하지 않았다면 컴파일러가 default constructor 도 자동으로 선언. 이러한 function들은 모두 public, inline 함수로 선언됨.

  3. 상속 관계가 있는 클래스의 destructor 선언 시 주의
  4. Base class의 destructor가 virtual로 선언되지 않은 경우, derived class의 compiler-generated destructor는 non-virtual로 선언됨.

  5. Default construtor가 자동으로 생성되지 않는 경우
  6. 사용자가 단 하나의 constructor라도 직접 선언한다면 default constructor는 자동으로 생성되지 않음.

  7. 그 외 함수가 자동으로 생성되는 경우
  8. Copy constructor나 copy assignment operator의 사용자 선언이 없으면, 이러한 함수가 실제로 call 되며, legal하게 작동되는 경우에 한해 컴파일러가 함수를 생성할 수 있음.

  9. 컴파일러는 derived class가 base class에서 private으로 선언된 copy assignment operator를 implicitly call하는 것을 허용하지 않음.

Summary

  • Compilers may implicitly generate a class's default constructor, copy constructor, copy assignment operator, and destructor.

Reference

  • Effective C++ by Scott Meyers

7월 11, 2016

[EC++ 04] Make sure that objects are initialized before they're used.


  1. Initialization 규칙
  2. 일반적으로 C++의 C 부분에 해당하는 경우 자동 initializing을 보장하지 않는데, C++의 non-C 부분에 해당하는 경우엔 해주는 경우도 있음. ex)array는 초기화 X, vector는 초기화 O.
    따라서 object를 사용하기 전에는 초기화를 직접 해주고 사용해야 함.

  3. Initialization과 assignment를 헷갈리지 말 것.
  4. C++은 ctor의 body에 들어가기 전에 object를 초기화함. 가급적이면 ctor의 밖에서 true initialization (member initialization list를 사용)할 것. ctor의 body 안에서 멤버에 =operator를 사용하는 경우 initialization이 아니라 assignment가 일어나 효율이 떨어짐. built-in type의 경우 initialization과 assignment 사이에 차이가 없지만 일관성 위해 initialization 사용하는게 좋음.
    const 나 reference 같은 경우는 member initialization list를 통해서만 초기화할 수 있음.

  5. Initialization order
  6. 상속 관계 안에서는 항상 base class가 먼저, derived class가 나중에 초기화됨(ECpp 12 참조). 한 class 안에서는 member를 선언한 순서대로 초기화됨.

  7. Order of initialization of non-local static objects
    • A static object
    • 생성된 때부터 프로그램이 종료되는 순간까지 존재하는 object.

    • Translation unit
    • 하나의 object file을 만드는 source code 단위. 대게 하나의 source file과 거기에 include 된 모든 파일.

    서로 다른 translation unit 에 속해있는 non-local static object의 initialization의 상대적인 순서는 undefined. 이런 non-local static object를 상대적인 순서를 맞춰가며 초기화하는 것은 매우 어렵기 때문에, 각 non-local statice var.을 static으로 선언한 function에 넣고, function 내에서 초기화하고 var.을 refence로 반환하도록 하는 것이 좋음. (단, 멀티스레드 환경에서 이런 static object를 포함하는 function 사용 시 주의해야 함.)


Summary

  • Manually initialize objects of built-in type, because C++ only sometimes initializes them itself.
  • In a constructor, prefer use of the member initialization list to assignment inside the body of the constructor. List data members in the initialization list in the same order they're declared in the class.
  • Avoid initialization order problems across translation units by replacing non-local static objects with local static objects.

Reference

  • Effective C++ by Scott Meyers

7월 10, 2016

enum, enum VS enum class(struct)


enum

  • enum(enumeration)
  • enumerator: namespace 안에 const 선언된 값
  • enum은 하나의 자료형으로 취급돼, 이를 param.로 받는 함수의 overloading 가능

enum VS enum class(struct)

  • enum (= unmanaged enum = standard enum)
  • namespace가 구분되지 않기 때문에 같은 이름의 enumerator가 존재할 수 없음.

  • enum class (= unmanaged enum = C++/CX enum)
  • 각각 자신의 namespace가 있어 같은 이름의 enumberator를 가질 수 있음.



Reference


7월 07, 2016

[EC++ 03] Use const whenever possible.

const가 붙는 위치에 따른 의미 변화


operator overloading 의 반환구에 const 를 붙여줌.

const Test


const Member Functions

  1. member function에 쓰이는 const 의 목적은 const object로 member function을 불렀을 때 어느 member function이 불릴지 판별하는 것. member function에 const 를 붙이는 이유는 크게 두가지.
    1. object 내용을 수정하는 함수와 그렇지 않은 함수를 구분할 수 있게 함.

    2. const object를 이용한 작업을 가능하게 하는데, 이는 C++의 성능 향상을 이루는 매우 중요한 방법 중 하나임(EC++ 20 참조).
  2. const에는 physical constantness와 logical constantness의 두가지 개념이 존재.
  3. const member function 안에서도 특정 member field를 수정해야하는 경우가 있는데, 이러한 member field에 키워드 mutable을 붙이면 수정이 가능.

Avoiding Duplication in const and Non-const Member Functions

같은 함수를 const 버전과 non-const 버전으로 구현하는 과정에서의 코드 중복을 막을 수 있는 방법.

Summary

  • Declatring something const helps compilers detect usage errors. const can be applied to objects at any scope, to function parameters and return types, and to member functions as a whole.
  • Compilers enforce bitwise constness, but you should program using logical constness.
  • When const and non-const member functions have essentially identical implementations, code duplication can be avoided by having the non-const version call the const version.

Reference

  • Effective C++ by Scott Meyers

6월 30, 2016

[EC++ 02] Prefer consts, enums, and inlines to #defines.

#define 으로 정의한 상수는 preprocessor에 의해 처리가 되어 컴파일러에 잡히지 않는다. 따라서 이 부분에서 실수가 일어나도 컴파일러가 이를 알려줄 수 없기 때문에, 가급적이면 #define의 다른 대체제를 사용하는 것이 좋다.

const

#define을 constants로 바꿔줄 때, 두가지 경우를 고려할 수 있다.

  • Defining constant pointer
  • const 위치에 따른 의미 변화에 유의. [EC++ 03]에서 자세히 다룸.

  • Class-specfic constants
  • static const int value = 5;


enum

"enum hack"

inline

#define function을 정의할 때는 문의 괄호에 반드시 신경써야 함.


Summary

  • For simple constants, prefer const objects or enums to #defines.
  • For function-like macros, prefer inline functions to #defines.

Reference

  • Effective C++ by Scott Meyers

6월 29, 2016

external linkage VS internal linkage

title: external linkage VS internal linkage
tag:

컴파일러는 컴파일 시 translation unit을 생성함.

translation unit
implementation file(*.cpp, *.cxx)에서 생성된 object 파일과 이 파일에서 include 된 모든 헤더 파일을 합친 것.
Internal linkage란 이 translation unit 안의 범위에 있는 것을 의미. 반대로 External linkage란 특정 translation unit의 외부에서도 존재하는 것(즉, 프로그램 어디서든(선언된 파일이 아닌 다른 파일에서도) 접근이 가능한 변수)을 의미.

예를 들어, static은 internal linkage를 가지며 선언된 파일 안에서만 접근이 가능함. 반면에 global variable은 external linkage를 가지며 선언된 파일 바깥에서도 extern 선언만 하면 프로그램 어디서든 접근이 가능함.


Reference

6월 24, 2016

reference type의 null 할당을 위한 static member null object(NullObject) 정의


Synopsis

C++에서 pointer 사용을 줄이기 위해서 가급적 reference type을 사용하려 하는데, pointer가 null 값을 가질 수 있는데 반해 reference type은 null을 가질 수 없어 reference type을 멤버로 갖는 객체 초기화 등에 불편. 이를 해결하기 위해 클래스에 static member로 해당 클래스 타입의 NullObject를 정의하고, 해당 클래스의 reference type이 null 값을 가져야 할 때 이 static null object를 줌.

Example



  1. case 1: NullObject가 정상적으로 작동함.
  2. case 2: NullObject의 주소를 확인 -> 주소 비교를 통해 현재 object가 NullObject인지 아닌지 체크 가능.
  3. case 3: NullObject inheritancy test 1
  4. case 4: NullObject inheritancy test 2

실제 이런 implementation을 사용 시에는 객체가 관련된 프로세스 과정에서 현재 객체가 NullObject인지 아닌지 객체 처리 전에 체크할 수 있는 nullCheck()나 isValid() 등의 멤버 함수를 추가로 정의.



더 생각해볼 점

  • NullObject는 const 선언이 되어야할까?
  • NullObject는 변경이 되선 안되므로 const 선언이 되는게 맞지만, 이 경우 이 NullObject를 받는 다른 reference type들도 모두 const 선언이 되어야하는 문제가 있음. 원래 NullObject는 reference type을 단순히 '임시로 초기화' 하기 위한 임시값인데, NullObject 때문에 reference type이 const reference type으로 선언이 되면 이후 이 reference type을 통해 가르킬 다른 객체들의 내부 값 수정이 불가능해짐.

  • NullObject가 move 또는 copy 된다면?
  • 이 경우도 문제가 생길 것 같은데.. move constructor나 copy constructor에 NullObject의 move나 copy를 막기 위한 NullObject 검사 과정이 필요함.

  • NullObject에 singleton 패턴을 응용할 수 있지 않을까?

Reference

  • -

6월 23, 2016

seekg() VS seekp(), tellg() VS tellp()


  • tellg()
  • get pointer의 현재 위치를 반환함. tellg() 는 input streams 와 함께 쓰이며, stream의 현재 포인터의 'get' position 을 반환함(get pointer의 현재 위치). get pointer는 input sequence에서 다음 input operation이 일어날 위치를 가르킴.

    • pos_type tellg()

  • tellp()
  • put pointer의 현재 위치를 반환함. tellp()는 output streams와 함께 쓰이며, stream의 현재 포인터의 'put' position을 반환함(put pointer의 absolute position을 반환). put pointer는 output sequence에서 다음 output operation이 일어날 위치를 가르킴.

    • pos_type tellp()

  • seekg
  • get pointer의 위치를 변경함. get pointer는 input stream과 관련된 pointer로, input stream과 연결된 source에서 읽어올 다음 위치를 가르킴.

    • istream& seekg(pos) pos로 pointer를 옮김.
    • pos는 absolute value(the value counting from begin of the file).

    • istream& seekg(offset, direction)
    • offset은 stream의 direction으로부터 offset을 direction은 offset을 counting할 기준점. (ios_base::beg, ios_bas::cur, ios_base::end 등이 존재.)

  • seekp
  • put pointer의 위치를 변경함. put pointer는 output stream과 관련된 pointer로, stream object의 output(put or write) file pointer의 위치를 가르킴. 대부분의 경우 stream object의 input file pointer의 위치도 함께 변경시킴.

    • ostream& seekp(pos) pos로 pointer를 옮김.
    • ostream& seekp(offset, direction)

example


output



Reference

6월 21, 2016

[EC++ 01] View C++ as federation of languages.


C++은 처음 도입된 이후 다양한 개념들을 흡수하며 발전한 결과 처음과는 다른 새로운 언어로 재탄생. 그러나 서로 다른 개념들을 통합하는 과정에서 수많은 예외 상황이 발생했고, 그 결과 C++ 에서 모든 상황에 적용되는 통일된 규칙을 찾는 것이 점점 어려워지고 있음. 이런 문제를 해결하기 위해 C++의 언어적 특성을 살펴볼 필요가 있음. C++은 크게 다음 4가지의 주된 언어적 특성을 가지고 있음.

  • C
  • Blocks, statements, preprocessor, built-in data types, arrays, pointers 등. 그러나 대부분의 경우 C++에서는 각 경우에 대응되는 더 나은 방법을 제공하고 있음.

  • Object-Oriented C++
  • encapsulation, inheritance, polymorphism 등

  • Template C++
  • C++의 generic programming 부분에 해당. Template은 TMP(Template Metaprogramming)이라는 새로운 패러다임을 만든 강력한 도구지만, 이를 잘 사용하지 않는다해도 C++에서 큰 문제는 없음.

  • The STL
  • STL(Standard Template Library)는 특별한 template library로, 이를 사용할 때는 STL의 특정한 conventions을 따라야 함.

이 각각의 언어적 특성들은 때때로 서로 갈등을 빗고, 그 결과 다양한 예외 규칙을 만들어 C++에 혼란을 초래함. 따라서 효율적인 프로그래밍을 위해서는, 이러한 sublanguage의 특성을 기억해두고 특정 상황에 따라 그에 맞는 sublanguage를 선택하여 유연하게 전략을 바꿀 수 있어야 함.


Summary

  • Rules for effective C++ programming vary, depending on the part of C++ you are using.

reference

6월 15, 2016

cin으로 대량의 데이터 읽을 때 주의 사항

cin으로 large data를 읽어야 하는 경우, cin.sync_with_stdio(false) 옵션으로 cin과 stdio의 sync를 해제.


explanation

cin은 기본 옵션으로 stdio와 syncronized되어 있음. FILE * 기반의 stdio와 iostream은 각각 구분되는 구현과 버퍼를 가지고 있기 때문에, 만약 두개가 같이 쓰인다면 문제가 생길 수 있음. 이런 문제를 해결하기 위해 stdio와 iostream를 syncronize하는데, 일반적으로 cin이 한번에 하나의 char씩만 읽도록 제한하는 방법을 사용.

그러나 이 때문에 input buffering을 할 수가 없어 많은 데이터를 읽을 경우 이 때문에 오버헤드가 굉장히 커지기 때문에, 대량의 데이터 입력이 필요한 경우 stdio와 cin의 sync를 해제해 주는 것이 좋음.


reference

6월 09, 2016

copy elision ,RVO, NRVO

복사 및 이동 생성자를 zero-copy pass-by-value (무복사 값에 의한 전달)로 최적화 하는 것. 특정 상황(아래 서술)에서 객체의 복사 및 이동 생성자를 생략함. 함수의 return 문과 관련되는 경우 이를 RVO(return by value, return의 argument가 생성자인 경우), NRVO(return by value, 함수 내 local variable을 반환하는 경우) 등으로 부르기도 함.


RVO (Return Value Optimization)

어떤 reference에도 bound되지 않은 nameless temporary 가 복사/이동될 때, 복사/이동 생성자가 생략되고 대신 복사/이동하려는 공간에 직접(바로) 할당됨. nameless temporary 가 return 문의 argument인 경우, 이러한 copy elision을 RVO라 부른다.


NRVO (Named Return Value Optimization)

vs2005부터는 이름있는 변수에도 RVO가 적용되기 시작함.

함수가 class type을 값으로 반환하고, 반환문의 expression이 함수의 파라미터나 catch-cluase의 파라미터가 아닐 때, 복사/이동 생성자가 생략되고 대신 복사/이동하려는 공간에 직접(바로) 할당됨. nameless temporary 가 return 문의 argument인 경우, 이러한 copy elision을 NRVO라 부른다.

단, NRVO는 non-debug mode(release mode), 최적화 옵션 /O1에서부터 적용됨.


사용 방법

return에 move(..)를 사용하지 않는다. 기본 implementaion은 다음과 같음.

  • X에 copy 또는 move constructor가 있으면, 컴파일러가 copy elision을 수행할 수 있음.
  • 이외의 경우, X에 move constructor가 있으면, move constructor가 실행됨.
  • 이외의 경우, X에 copy constructor가 있으면, copy constructor가 실행됨.
  • 이외의 경우, 컴파일 타임 에러가 생략됨.


주의

만약 if 문과 같이 multiple return paths를 갖는 경우 (N)RVO가 수행되지 않음. 그 밖에 컴파일러에 따라 디버그 모드 등 특정한 상황에서 copy elision을 수행하지 않으므로 주의해야 함.


example


  

왼쪽: result in debug mode, 오른쪽: result in non-debug mode(release mode) with /O1 option


reference

6월 08, 2016

cv-qualified type 이란?

type specifier에서 constness나 volatility를 나타내는데 사용되는 표현. const , volatile , mutable 등이 있음.


cv-unqualified type

cv-qualified 가 아닌 모든 type.


reference

5월 30, 2016

ODBC API


연결 과정

  1. ODBC Data Source 설정 참고)windows 10에서 ODBC data source 설정 방법
  2. DB에 연결
    1. Header 파일 include: sql.h , sqltypes.h , sqlext.h
    2. SQLAllocHandle(..): Environment handle (object) 할당
    3. SQLSetEnvAttr(..): Environment handle 설정
    4. SQLAllocHandle(..): Connection handle (object) 할당
    5. SQLSetConnectAttr(..): Connection handle 설정
    6. SQLConnect(..) (또는 SQLDriverConnect(..)): DB와 연결
    7. SQLDriverConnect(..)는 GetDesktopWindow() 사용해 windows.h 사용.

    8. SQLAllocHandle(..): Statement handle (object) 할당
    9. (SQLSetStmtAttr(..): Statmenet handle 설정)

    ODBC API에 param.로 char string을 전달 시 반드시 wchar 형으로 전달해야 함. 참고) wide character type (wchar_t) 란?

  3. statement 실행
  4. Query 결과 확인
  5. DB와의 연결 해제
    1. SQLFreeHandle(..): Statement handle 해제
    2. SQLDisconnect(..): DB 연결 해제
    3. SQLFreeHandle(..): Connection handle 해제
    4. SQLFreeHandle(..): Environment handle 해제

statement 실행

query 직접 입력

  • SQLExecDirect(..): SQL 문 실행

querying의 반복 실행이 없는 경우 가장 적합한 방식.


prepared procedure

  1. SQLBindParameter(..): SQL statement의 param. marker에 버퍼를 bind.
  2. SQLPrepare(..): query 실행을 위한 SQL string을 준비.
  3. SQLExecute(..): prepared statement를 실행. 만약 param. marker가 statement 에 존재한다면 param. marker 변수의 현재 값을 사용.

query 결과 확인

query 결과로부터 데이터 추출

  1. SQLBindCol(..): 어플리케이션 데이터 버퍼를 result set의 column에 bind
  2. SQLFetch(..): result set의 다음 rowset의 데이터를 가져와서 bound된 모든 column에 대한 데이터를 리턴.
  • SQLFetchScroll(..): result set의 다음 rowset의 데이터를 가져와서 bound된 모든 column에 대한 데이터를 리턴. rowset은 절대/상대/북마크 위치로 설정가능.

column-wise, row-wise 등 다양한 데이터 추출 방법이 존재. 참고) Retrieving Results (Advanced) |MSDN


result set 관련 정보 확인

  • SQLDescribeCol(..): result set metadata를 알아내는데 사용
  • SQLColAttribute(..): result set metadata를 알아내는데 사용
  • SQLDecscribeCol VS SQLColAttribute SQLDecscribeCol 은 항상 정해진 5개의 정보를 리턴. SQLColAttribute 는 사용자가 지정한 정보 하나만을 리턴하는 대신에 더욱 다양한 정보에 대해 알아볼 수 있음. SQLDescribeCol and SQLColAttribute |MSDN

  • SQLNumResultCols(..): result set의 column 개수를 반환
  • SQLRowCount(..): UPDATE, INSERT, DELETE로 영향 받는 row의 개수를 반환.

오류 처리

  • SQLError(..): 오류나 스테이터스 정보를 반환

기타 함수

  • SQLGetInfo(..): connection과 관련된 드라이버와 data source에 관한 전반적인 정보를 반환

code example



reference

5월 27, 2016

ODBC Fundamentals: Descriptor Handles

descriptor란 어플리케이션이나 드라이버에게 보여지는 SQL statment의 param. 나 result set의 칼럼과 같은 메타데이터의 collection을 의미한다. descriptor는 다음 네가지 중 어떠한 역할도 맡을 수 있다.

  • Application Parameter Descriptor (APD).
  • SQL statement의 param.에 bound된 어플리케이션 버퍼에 대한 정보(그 버퍼의 주소, 크기, C data types 등)을 가짐.
  • Implementation Parameter Descriptor (IPD).
  • SQL statement의 파라미터에 관한 정보(SQL data type이나 크기, nullability)를 가짐.
  • Application Row Descriptor (ARD). result set의 칼럼에 bound된 어플리케이션 버퍼데 대한 정보(그 버퍼의 주소나 크기, C data type 등)를 가짐.
  • Implementation Row Descriptor (IRD). result set의 칼럼에 대한 정보(SQL data type이나 크기, nullability 등)를 가짐.

statement가 할당될 때 위 네개의 descriptors도 자동으로 할당되지만, 어플리케이션에서 SQLAllocHandle(..) 을 통해서 직접 할당할 수도 있으며 이를 explicityly allocated descriptors라 한다. 이런 descriptors는 connection에 할당이 되어 마찬가지로 그 connection에 할당된 하나 이상의 statements와 연관되어 APD 나 ARD의 역할을 맡는다.
ODBC에서 수행되는 대부분의 operation은 explicityly allocated descriptors 없이 수행 가능하지만, 때로 이런 descriptors가 몇몇 operation의 편리한 shortcut으로 사용할 수도 있다. (reference 참조)


reference

5월 26, 2016

wide character type (wchar_t) 란?

wide charater란 전통적인 8-bit character보다 더 큰 사이즈를 가지는 character datatype을 말함. datatype 사이즈가 커져 더 큰 character sets을 표현할 수 있다. UTF-16 little endian이 마이크로소프트의 wchar_t 표준이지만, wchar_t는 플랫폼 별, 컴파일러 별로 8 bit 에서 32 bit 까지 다양한 wide character implementation을 가지고 있어 wchar_t의 크기는 통일이 되지 않았다. 이런 이유로 프로그램이 multi platform에서 사용이 될 예정이라면 유니코드 저장 용도로 wchar_t을 사용해서는 안된다.

C/C++ 소스 코드는 보통 US-ASCII나 ISO-2022를 따르는 MBCS로 작성된다. 따라서 소스 코드에선 원칙적으로 wchar_t 문자열 사용이 불가능하다(ASCII와 호환되는 MBCS나 UTF-8만 가능). 이와 같이 소스 코드에서 wide character를 받지 않기 때문에, 소스 코드 상에서 L 문자를 문자열 앞에 붙여 wide character를 표현한다.

wchar_t * wchar = L"wide character string"

그러나 옛날 버전의 gcc 컴파일러에서는 이런 표현을 지원하지 않는 경우가 있기 때문에 확인이 필요하다.




reference

5월 19, 2016

SQL Server connection error: 26

증상

Microsoft SQL Server Management Studio 실행 후 Server(Database engine) Connection 시 접속 불가 현상.

MS SMS connection window


MS SMS error message



해결책

SQL Server 의 log on 대상을 built-in:local system으로 바꿔줌.

  1. SQL Server Configuration Manager 실행
  2. SQL Server Service items 설정 변경
    1. SQL Server(SQLEXPRESS) > properties
    2. log on tab 선택
    3. Log on as: built-in account > Local System 지정
    4. 필요한 경우 해당 서비스 리부트
  3. SQL SMS connection window에서 Server name을 .\SQLEXPRESS 로 변경 후 접속

reference

5월 18, 2016

windows 10에서 ODBC data source 설정 방법

C++에서 MSSQL DB을 연결하는 data access programming을 하기 위해선 ODBC data source를 설정해야 함.

  1. ODBC data source 찾기
  2. ODBC data source 설정

specifications

  • windows 10
  • ODBC driver 11
  • SQL Server 2014 Express

ODBC data source 찾기

data source 설정에 접근하는 방법은 크게 두가지가 있음.

  • 시작 메뉴에서
  • all aps -> Windows Administrative Tools -> ODBC data sources (32bit/64bit)

  • settings panel에서
  • Find a setting -> ODBC -> Set up ODBC data sources (32bit/64bit)

주의
32bit 또는 64bit 선택은 OS가 아니라 application을 따라감. 즉 자신이 build하고 run하는 application의 bit에 맞춰 선택
ODBC Administrator tool displays both the 32-bit and the 64-bit user DSNs in a 64-bit version of Windows |support.microsoft.com

ODBC data sources 설정

  1. "User DSN" tab 선택
  2. User DSN 외에도 여러 탭이 있는데, 각각 만드려는 ODBC Data source에 접근 범위를 설정하는 것. 시스템에 여러 user가 있고 모두 같은 data source를 쓰려면 System DSN으로 하는게 편함.

    • User DSN: 현재 user만 사용할 수 있으며, 현재 컴퓨터에 local인 data source를 생성.
    • System DSN: 시스템의 모든 user가 사용할 수 있으며, 현재 컴퓨터에 local인 data source를 생성.
    • File DSN: 동일한 드라이버를 설치한 모든 사용자들이 공유할 수 있는 파일 기반 data source를 생성. 현재 컴퓨터에 local 아니어도 가능.
    • Tracing: 이 탭은 ODBC 드라이버 관리자가 ODBC 함수 호출을 추적하는 방법을 지정. 캡쳐된 내용은 로그 파일에 저장됨.
    • Connection Pooling: 응용 프로그램이 연결 풀에서 연결을 다시 사용할 수 있도록 함. 연결 풀링을 사용할 때 연결 재시도 대기 시간 및 시간 제한(초)을 변경 가능.

  3. "Add" -> "ODBC Driver 11 for SQL Server" 선택
  4. Access나 Excel, SQL Server, ODBC Driver 등 data source를 연결할 드라이버를 지정 가능. ODBC를 이용해서 연결하므로 "ODBC Driver 11 for SQL Server" 또는 SQL Server 선택.

    • ODBC Driver 11 for SQL Server
    • SQL Server가 local인 경우 사용 가능.

    • SQL Server
    • SQL Server가 local이거나 remote 인 경우 사용 가능. 이후 설정 과정에서 "Client Configuration"을 named pipe(local), 혹은 TCP/IP(remote)로 설정을 바꿔줘야 함.

    • SQL Server Navtive Client 11.0
    • application이 C 언어로 작성되는 경우. (확인 필요)

  5. Name에 원하는 서버 이름, Server에 연결할 서버 작성
    • Name: 외부에 표시되는 서버 이름
    • Description: 외부에 표시되는 서버 설명
    • Server: 접속할 SQL server. SQL Server Management Studio에서 connection 시의 Server Name을 입력.

  6. Authentication 방법 설정
  7. Default Database 설정
  8. 기본은 master. SQL Server 내에서 미리 작성해놓은 Database 선택.

  9. 기타 설정

ODBC data sources 설정 - remote(TCP/IP)인 경우


reference

5월 12, 2016

MySQL 설치 관련 정보


  • MySQL server (필수)
  • 서버(DB)

  • MySQL for Visual Studio
  • MySQL 서버(DB) 관리 시 커맨드 라인에서 DDL이나 DML을 사용하지 않고도 Visual Studio에서 GUI로 편집할 수 있게 해주는 도구.

    주의
    MySQL for V.S. 와 MySQL connector 설치 시 반드시 MySQL for V.S. 를 먼저 설치한 후 MySQL connector를 나중에 설치해야 함.

  • MySQL connector/C++ (필수)
  • C++에서 MySQL 서버(DB)에 접근할 수있게 연결해주는 라이브러리. 크게 source file 형태, binary 형태로 제공. binary 형태의 제공은 미리 컴파일 되어있어 별도의 컴파일 과정 없이 사용 가능하나, 컴파일러 버전에 따라 호환이 되지 않을 수도 있음. 따라서 MySQL 측은 source file에서 자신이 사용하는 컴파일러를 통해 binary를 직접 생성할 것을 권장.

  • MySQL workbench C/E
  • MySQL 서버(DB)를 GUI로 편집할 수 있게 해주는 도구.

  • MySQL on Windows: MySQL INstaller
  • 위의 MySQL 서버와 tool들을 모두 포함한 all-in-one 버전.

    주의
    다만, 설치 과정에서 Visual studio와 MySQL의 bit 버전(86/64)을 동일하게 맞춰줘야하는데, 개별 설치하는 경우 각각 bit 버전을 맞출 수 있는 반면에서 자동 설치를 선택 시 비트 버전이 제각각이 될 수 있으니 주의.



reference

5월 10, 2016

commit 날짜 수정하는 법



  • author date: commit의 작성자가 commit을 작성한 날짜. commit message 안에 포함.
  • commit date: commit이 이루어진 날짜


git commit --amend --date="`date`" 사용 -> author date 가 현재 날짜로 바꿈.

GIT_COMMITTER_DATE="`date`" git commit --amend --date="`date`" -> commit date 와 author date 둘다 현재 날짜로 바꿈.




reference

5월 09, 2016

MSSQL ODBC vs OLEDB vs ADO


  • ODBC
  • OLEDB
  • ADO
  • ADO.NET
  • 기타

ODBC (Open DataBase Connector)

  1. 1992년 소개
  2. SQL data source만 처리 가능
  3. base는 C++ (MFC database classes가 ODBC를 베이스로 하고 있음), Java(JDBC)
  4. platform independent, 윈도우 리눅스 상관 없이 사용가능.

OLEDB (Object Linking and Embedding DataBase

  1. 1996년 소개
  2. ODBC가 SQL data만 처리 가능한데 반해, non-SQL data source도 처리 가능
  3. C++, Java
  4. COM을 이용하기 때문에 윈도우 종속적.
  5. SQL data source 접근할 때는 ODBC를 통해 접근한다는 설명도 있고 ODBC 없이 직접 접근할 수 있다는 설명도 있음. (확인 필요).
  6. OLE DB 는 deprecated 됨.
  7. Microsoft is Aligning with ODBC for Native Relational Data Access |blog.msdn.microsoft

ADO (ActiveX Data Object)

  1. 1996년 소개
  2. OLEDB의 high level interface. 다양한 언어에서 사용 가능.
  3. C++, C#, Java, VB, Script 언어(웹 어플리케이션)
  4. DB 접근 시 OLEDB를 거쳐가기 때문에 윈도우 종속적.
  5. 요즘 잘 안쓰인다는 설명이 있음. 확인 필요. //rev

ADO.NET

  1. 2002년 소개
  2. OLE DB 및 ODBC를 통해 노출되는 데이터 소스, SQL Server 및 XML과 같은 데이터 소스에 대한 일관성 있는 액세스를 제공
  3. C#, Java, VB, Script 언어(웹 어플리케이션)
  4. DB 접근 시 ADO를 거쳐가기 때문에 윈도우 종속적.
  5. 요즘 잘 안쓰인다는 설명이 있음. 확인 필요. //rev

기타

  1. DAO
  2. ODBC와 유사하나 ODBC가 다양한 데이터베이스에 접근할 수 있는데 반해 DAO는 local machine에 존재하는 데이터베이스에 빠르게 접근하기 위한 목적으로 개발됨.

  3. RDO
  4. 서버에 기반을 둔 데이터베이스를 위한 기술로 RDS가 뒤를 이은 후 현재는 잘 사용되지 않음.


그림1


그림2 (MSDN)


reference

5월 06, 2016

git cherry-pick 사용법

Given one or more existing commits, apply the change each one introduces, recording a new commit for each. This requires your working tree to be clean (no modifications from the HEAD commit).

다른 branch로부터 특정 commit을 가져와서 추가. 추가한 commit으로 새로운 commit이 생기며(hash값이 다름) 해당 commit에서 이루어진 변경 사항만 적용됨.

더 연구할 점

  1. reference에 따르면 cherry-pick하는 commit 만의 변경 사항을 가져올 것 같은데, 실제로는 conflict("both modified: 파일명") 가 발생하며 현재 branch와 cherry-picking branch의 공통 부모로부터 cherry-picking commit까지 모든 commit을 가져옴 (변경 사항을 누적시켜 모두 가져옴).
  2. 새로운 파일을 생성하고 만든 첫 commit을 cherry-pick하는 경우에는 merge conflict 없이 cherry-picking 됨
  3. 만약 새로운 파일을 생성하고 해당 파일을 수정하며 여러번 commit하고 이중 하나의 commit만 cherry-picking 하는 경우 conflict("deleted by us: 파일명") 발생하며 현재 branch와 cherry-picking branch의 공통 부모로부터 cherry-picking commit까지 모든 commit을 가져옴 (변경 사항을 누적시켜 모두 가져옴).

reference

5월 03, 2016

MSSQL Server 기초 개념

SQL Server 2014 Express advanced service

SQL db 본체. MSSQL Database와 DB 관리 도구 등의 구성 요소를 포함하고 있는 패키지. 요금제, 제공하는 서비스의 종류나 coverage에 따라 Enterprise, BI, Express(무료) 등 에디션이 구분됨. 또한 연도에 따라 2012, 2014, 2016 등 버전이 구분되며, 같은 버전 안에서 포함된 구성요소에 따라 SQL Server Express 도구, SQL Server Management studio, SQL Server Express with advanced service(모든 구성요소 포함) 등 패키지가 구분됨.


SQL ODBC driver

MySQL connector 와 같이 DB와 C++을 연결해 주는 라이브러리의 일종으로, 어플리케이션 내에서 작성된 쿼리를 DB로 보내고 결과 set을 받아오는 등 C++ 어플리케이션과 MSSQL 서버를 연결해 주는 역할. JDBC(java), .net(C#) 등 여러 종류의 드라이버가 존재.


reference

4월 21, 2016

multi-dimensional vector로 2차원 행렬 구현하기


vector를 요소로 갖는 벡터를 선언하여 2-dim array를 구현 가능. 이 경우, 각각의 row는 별도의 vector 이므로, n x n 으로 딱 떨어지는 행렬 뿐 아니라 row마다 서로 다른 크기의 column을 가지게 하는 것도 가능.

예제




단, method1 의 경우 column의 크기가 커지는 경우 vector 재할당이 발생해 효율이 떨어질 수 있음. 특히 새로운 row의 추가로 인한 vector 재할당은 단순히 그 row만 영향을 받는게 아니라 전체 row에 대해 재할당이 일어나기 때문에, 각 row 별로 vector 들이 전부 재할당 되어 더욱 심각한 비효율을 초래함.



결과

========================
0 1 2
3 4 5

========================
1 2 3
4 5 6

========================
0 0 0
0 0 0



reference

4월 15, 2016

STL unordered map

associative container. 각 element는 Hash 함수를 통해 bucket이라는 하위 시퀀스로 약하게 정렬됨. bucket 간의 탐색 시간은 constant, bucket 내에서의 탐색 시간은 linear함.
요소를 제거하는 경우 해당 요소의 iterator는 무효화되지만, 그외 다른 iterator는 유효함.

사용법

  • key와 element의 std::pair를 element로 가짐
  • iterator를 사용한 sequential한 반복 탐색, range 반복 탐색 가능(begin(), end())
  • 요소 삽입은 insert(..) 혹은 emplace(..) 사용
  • operator[key]를 이용한 random access 가능. 만약 존재하지 않는 key에 접근하는 경우 해당 key를 갖는 새로운 element 생성
  • find(key)로 탐색 가능. 반환형은 해당 element의 iterator
  • count(key) vs size(): count는 지정된 key를 갖는 element의 수를 반환, size는 map 내의 element 총개수를 반환. unorded_map의 경우 모두 다른 key 값을 갖기 때문에, 해당 key의 element가 있으면 1, 없으면 0 반환
  • erase(..): key나 iterator, ranged iterator로 지울 element 선택 가능. 각 경우에 따라 반환형이 달라지는데, key의 경우 지워진 element의 개수, iterator의 경우 지워진 element 중 마지막 element의 iterator를 반환
  • clear(): 모든 element의 destructor를 부르고 container에서 drop시킴. size는 0이 됨

예시



references

4월 13, 2016

git rebase -i 사용법

rebase 과정

  1. txt 파일에 1 2 3 4 5 6 7 작성 후 각각 commit.

  2. <text 파일 내용>


    <commit log> 

    현재 HEAD는 "commit 7"을 가리키고 있음.

  3. rebase 실행: git rebase HEAD~7 -i
    • HEAD 는 어느 commit 까지 rebase 할지를 알려주고 -i 옵션은 interactive 하게 rebase를 실행함을 의미.
    • HEAD~n 에서 n은 commit log에서 첫번째 commit까지 rebase하는 경우 1, 2번째까지 rebase하는 경우 2, ... , n번째 commit까지 rebase하는 경우 n이 됨. 즉, 위의 예시에서 "commit 7"이 HEAD~1이 됨
  4. -i 옵션으로 인해 rebase 대화창이 pop-up
    • commands를 입력해 commit 내용 편집, 삭제, 순서 변경 등의 작업을 수행. 메모장을 저장하고 닫으면 commands에 따라 rebase가 수행됨.
    • <변경 전 commit> 
      <수정 된 commit> 
    • rebase 메시지에서 commit 정렬 순서: 오래된 commit이 위쪽에, 최근에 수행한 commit이 아래쪽으로 정렬됨.
    • 병합 순서: commit이 squash 될 때는 위쪽의 commit으로 병합
    • 오래된 commit에 차곡차곡 변경 사항이 쌓임. 위의 예에서는 "commit 2" 가 "commit 1"에 병합. "commit 6" -> "commit 5" -> "commit 4"에 병합.

    • rebase 수행 후: "commit 7"
    • <commit log> 
      <text file contents> 
    • rebase 수행 후: "commit 4"
    • "commit 4"에 "commit 5,6"의 내용이 병합. 위쪽(보다 오래된 commit)에 변경 사항이 누적됨.

      <text file contents> 
    • rebase 수행 후: "commit 1"
    • "commit 1"에 "commit 2"의 내용이 병합. 위쪽(보다 오래된 commit)에 변경 사항이 누적됨.

      <text file contents> 

references

Rewriting history