2016의 게시물 표시

windows 운영체제에서 git clone 중 error: unable to create file ... Filename too long

windows에 git clone으로 source를 받을때 Filename too long error가 발생하는 경우가 있는데 이것은 windows 경우 filename(path) limitation(260자) 이 있기 때문이다. 이것을 해제하기 위해서는 cmd 창에서 아래와 같이 입력해주면 된다. C:\> git config core.longpaths true

Raspberry pi 한글 설정 및 chromium 설치

Raspbian apt-get repository 갱신 및 설치된 sw를 최신 version으로 upgrade $ sudo apt-get update $ sudo apt-get upgrade Locale 및 keyboard 설정 $ sudo raspi-config "5. Internationalisation Options"  선택 "Change Locale" 선택 목록에서  " en_US.UTF-8 UTF-8", "ko_kr.UTF-8 UTF-8"  선택(space로 복수개 선택할 수 있음)  "Change Keyboard Layout" 선택 목록에서 Generic 105-key 한글 폰트 및 ibus 설치 $ sudo apt-get ibus ibus-hangul ttf-unfonts-core $ sudo reboot 설치 후 재실행 하면 오른쪽 상단에 US혹은 태극 모양의 아이콘이 추가되어 있다. 해당 아이콘을 오른쪽 클릭하면 " 기본설정" 메뉴가 있고 여기서 한영전환 단축키를 설정 Chromium(+youtube) 설치  $ wget -qO - http://bintray.com/user/downloadSubjectPublicKey?username=bintray | sudo apt-key add - $ echo "deb http://dl.bintray.com/kusti8/chromium-rpi jessie main" | sudo tee -a /etc/apt/sources.list $ sudo apt-get update $ sudo apt-get install -y chromium-browser rpi-youtube Terminator(Terminal) 설치 $ sudo apt-get install terminator

Raspberry pi 에 Bluetooth사용을 위한 bluez설치 및 실행

Raspberry pi 에 Bluetooth 를 사용하기 위해서는 기본적으로 bluez 라는 lib을 설치해야 한다. bluez를 설치 하기 위해서는 다음의 lib이 먼저 설치 되어야 한다. $ sudo apt-get update $ sudo apt-get install -y libusb-dev libdbus-1-dev libglib2.0-dev libudev-dev libical-dev libreadline-dev 그다음 http://www.bluez.org 에서 bluez source 를 다운받아 압축을 푼 후 compile & install을 수행한다. $ ls bluez-5.40.tar.xz/ $ tar xvf bluez-5.40.tar.xz $ cd bluez-5.40 $ ./configure $ make $ sudo make install 설치가 완료되면 hciconfig 명령어로 bluetooth 가 인식되는지 확인한다. $ hciconfig hci0: Type: BR/EDR Bus: USB BD Address: 00:1A:7D:DA:71:02 ACL MTU: 310:10 SCO MTU: 64:8 UP RUNNING RX bytes:2117911 acl:0 sco:0 events:51857 errors:0 TX bytes:1947 acl:0 sco:0 commands:45 errors:0 원래는 위와 같이 나와야 하지만... -_- 이전에 Bluetooth 환경 설정을 위해 이전에 이것 저것 다른 lib을 많이 깔아놔서 인지 hciconfig를 수행하면 위의 "UP RUNNING" 이 "DOWN"으로 되어 있고 Bluetooth가 동작하지 않는 문제가 있었다. 이경우 bluetooth를 켜기 위한 다음의 명령어를 수행하면 아래와 같은 메세지가 출력되면서 실패한다. $ sudo hciconfig hci0 up device hc

Array Pointer

1 2 3 4 int x[] = {1,2,3,4,5}; int (*p1)[5]; int *p2[5]; 위 p1와 p2의 차이는? p1은 int[5]의 pointer이고,  p2는 int*를 item으로 가지는 길이 5의 array이다.  위 두 line이 위와 같이 해석되는 이유는 c 컴파일러에서는 * 보다 []가 우선순위를 가지기 때문이다. 그러므로 p1이 포인터임을 명시하고 싶을 경우 우변에 []가 있다면 반드시 ()를 넣어 우선순위를 정해주어야 한다. 위 코드의 p1, p2는 다음과 같이 해석된다. p1 is pointer of int[5]  p2 is array[5] of int*  1 2 3 4 5 int a1[3][2] = { { 1,2 },{ 3,4 },{ 5, 6 } }; int(*p1)[3][2] = &a1; int *p2[3][2]; int (*p3)[2] = &a1[0]; 위의 의미를 해석해 보면 p1 is pointer of int[3][2];  p2 is array[3][2] of int*  p3 is pointer of int[2]  이 내용을 이해했다면 다음의 두 값의 차이를 확실히 알 수 있을 것이다. 1 2 3 4 int x[] = {1,2,3,4,5}; int* p1 = x; int (*p2)[5] = &x; 이 둘의 차이는 각각 1을 더했을 때 확인 할 수 있다. p1은 sizeof(int) 만큼 증가하고,  p2는 sizeof(int)*5 만큼 증가한다.

Iterator category

STL에서는 iterator의 category를 알고 사용하는 것이 매우 중요한데 그 이유는 category 별로 사용할 수 있는 generic algorithm 이 다르기 때문이다. 예를 들어 list<>의 내용을 generic algorithm인 sort() 를 사용하여 정렬할 수 없는데 그 이유는 sort()는 random access iterator만 parameter로 입력 받을 수 있기 때문이다. STL의 Iterator는 수행 가능한 operator에 따라 다음과 같이 분류된다. category operator input = *p, ++ output *p =, ++ forward *p =, = *p, ++ bidirectional *p =, = *p, ++, -- random access *p =, = *p, ++, --, +, -, [] STL의 Container 각각이 가지고 있는 iterator의 category는 다음과 같다. container category array, vector, deque, string random access list bidirectional Generic algorithm이 요구하는 iterator의 category는 다음과 같다. generic algorithm category find(), advance() input reverse() bidirectional sort() random access list container의 경우 bidirectional iterator를 지원하기 때문에 generic sort() 를 사용 할 수 없다. 대신 list의 경우는 sort()를 직접 지원한다. 직접 만든 Container를 generic algorithm 에서 사용할 수 있도록 하기 위해서는 이러한 iterator의 특

Iterator 무효화

vector v(10, 1);  vector ::iterator p = v.begin();  cout << *p << endl;  v.resize(20);  cout << *p << endl; 이경우 기존 생성한 iterator는 무효화 된다. 실행시 마지막 라인에서 run-time error가 발생한다. 하지만 size를 줄이는 경우는 해당되지 않는다. vector v(10, 1);  vector ::iterator p = v.begin();  cout << *p << endl;  v.resize(5);  cout << *p << endl; 이유는 container 재할당 시 크기가 클 경우 메모리를 재할당 하고 작을 경우 기존 메모리를 활용하는데, Iterator는 내부에 container의 메모리에 대한 pointer를 가지고 있기 때문에 resize()의하여 메모리를 재할당 할 경우 Iterator 무효화가 발생한다.

Test double

테스트시 테스트의 결과의 신뢰성을 떨어뜨리는 주요 원인은 테스트 대상 객체가 다른 객체와 강한 결합되어 있음으로 인해 외부 요인(강한 결합된 다른 객체)에 의해 테스트 결과가 변경될 수 있다는 것이다. 이러한 점은 Test double을 통하여 해결 할 수 있다. 테스트 대상 코드를 격리하고, 속도를 개선하고, 예측 불가능한 요소를 제어하고, 특수한 상황을 시뮬레이션하고, 감춰진 정보를 얻기 위해 기존 객체를 대체하여 사용가능한 대역 객체를 통틀어 test double이라 한다.  Test double을 사용하기 위해서는 객체 간의 강한 결합을 제거해야 한다. 강하게 결합된 객체를 interface를 상속받도록  하여 약한 결합으로 refactoring을 하면, 해당 interface를 대역 객체로 대체함으로서 해당 객체에 대한 신뢰할 수 있는 테스트작성이 가능하다. 이러한 대역 객체는 역할에 따라 아래와 같이 나뉜다. Stub 의존 class를 원하는 형태로 제어하기 위함 외부 의존 class나 협력 객체를 대신함으로서 테스트 범위에서 제거 Fake 의존하는 객체가 느리거나 준비되지 않았을때 해당 객체를 대용하기 위함 Spy 접근 불가능한 내부 정보를 테스트 하기 위함 목격한 일을 기록하여 나중에 테스트시 확인 할 수 있도록 함 Mock 기대한 상호작용이 진짜 발생하였는지 확인하는 행위기반 검증을 위한 테스트 대역 반환값이 없거나 상태 확인만으로 기대 동작을 보장할 수 없을경우 사용 Stub과 fake는 테스트 범위에 포함되지않는 객체를 대신하기위해 만드는 점에선 역할이 겹치는점에선 역할이 같지만 이둘을 구분하는 기준은 내부로직의 유뮤이다.  Stub은 복잡한 로직없이 입력에 대한 정해진 결과를 단순히 반환하지만 Fake는 business logic을 가지고 "동작"한다는 점에서 차이가 있다.