rozellea의 등록된 링크

키자드에 등록된 총 317개의 포스트를 확인하실 수 있습니다.

Naver Blog

3편 : 라즈베리 파이 기본 설정해주기

라즈베리 파이 기본 설정해주기 프로젝트 목차 0편 : 개요 1편 : 라즈베리 파이에 라즈비안(OS) 설치(키보드, 마우스, 모니터 없이 설치) 2편 : VNC 뷰어로 라즈베리 파이 원격 제어 3편 : 라즈베리 파이 기본 설정해주기 4편 : 라즈베리 파이 한글 설정 5편 : 라즈베리 파이 카메라 사용하기 6편 : 라즈베리 파이에 OpenCV 설치하기 7편 : 실시간 얼굴인식 카메라 | 파이썬(python)으로 라즈베리 파이 카메라 사용하기 8편 : 실시간 얼굴인식 카메라 | 실시간 카메라 영상에서 사람 얼굴 판별하기 9편 : 실시간 얼굴인식 카메라 | OpenCV Haar feature-based cascade classifiers 사용하기 10편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 데이터 수집 11편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 학습 12편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시

Naver Blog

4편 : 라즈베리 파이 한글 설정

라즈베리 파이 한글 설정 프로젝트 목차 0편 : 개요 1편 : 라즈베리 파이에 라즈비안(OS) 설치(키보드, 마우스, 모니터 없이 설치) 2편 : VNC 뷰어로 라즈베리 파이 원격 제어 3편 : 라즈베리 파이 기본 설정해주기 4편 : 라즈베리 파이 한글 설정 5편 : 라즈베리 파이 카메라 사용하기 6편 : 라즈베리 파이에 OpenCV 설치하기 7편 : 실시간 얼굴인식 카메라 | 파이썬(python)으로 라즈베리 파이 카메라 사용하기 8편 : 실시간 얼굴인식 카메라 | 실시간 카메라 영상에서 사람 얼굴 판별하기 9편 : 실시간 얼굴인식 카메라 | OpenCV Haar feature-based cascade classifiers 사용하기 10편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 데이터 수집 11편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 학습 12편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각

Naver Blog

5편 : 라즈베리 파이 카메라 사용하기

라즈베리 파이 카메라 사용하기 프로젝트 목차 0편 : 개요 1편 : 라즈베리 파이에 라즈비안(OS) 설치(키보드, 마우스, 모니터 없이 설치) 2편 : VNC 뷰어로 라즈베리 파이 원격 제어 3편 : 라즈베리 파이 기본 설정해주기 4편 : 라즈베리 파이 한글 설정 5편 : 라즈베리 파이 카메라 사용하기 6편 : 라즈베리 파이에 OpenCV 설치하기 7편 : 실시간 얼굴인식 카메라 | 파이썬(python)으로 라즈베리 파이 카메라 사용하기 8편 : 실시간 얼굴인식 카메라 | 실시간 카메라 영상에서 사람 얼굴 판별하기 9편 : 실시간 얼굴인식 카메라 | OpenCV Haar feature-based cascade classifiers 사용하기 10편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 데이터 수집 11편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 학습 12편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시

Naver Blog

6편 : 라즈베리 파이에 OpenCV 설치하기

라즈베리 파이에 OpenCV 설치하기 프로젝트 목차 0편 : 개요 1편 : 라즈베리 파이에 라즈비안(OS) 설치(키보드, 마우스, 모니터 없이 설치) 2편 : VNC 뷰어로 라즈베리 파이 원격 제어 3편 : 라즈베리 파이 기본 설정해주기 4편 : 라즈베리 파이 한글 설정 5편 : 라즈베리 파이 카메라 사용하기 6편 : 라즈베리 파이에 OpenCV 설치하기 7편 : 실시간 얼굴인식 카메라 | 파이썬(python)으로 라즈베리 파이 카메라 사용하기 8편 : 실시간 얼굴인식 카메라 | 실시간 카메라 영상에서 사람 얼굴 판별하기 9편 : 실시간 얼굴인식 카메라 | OpenCV Haar feature-based cascade classifiers 사용하기 10편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 데이터 수집 11편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 학습 12편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을

Naver Blog

7편 : 실시간 얼굴인식 카메라 | 파이썬(python)으로 라즈베리 파이 카메라 사용하기

실시간 얼굴인식 카메라 | 파이썬(python)으로 라즈베리 파이 카메라 사용하기 프로젝트 목차 0편 : 개요 1편 : 라즈베리 파이에 라즈비안(OS) 설치(키보드, 마우스, 모니터 없이 설치) 2편 : VNC 뷰어로 라즈베리 파이 원격 제어 3편 : 라즈베리 파이 기본 설정해주기 4편 : 라즈베리 파이 한글 설정 5편 : 라즈베리 파이 카메라 사용하기 6편 : 라즈베리 파이에 OpenCV 설치하기 7편 : 실시간 얼굴인식 카메라 | 파이썬(python)으로 라즈베리 파이 카메라 사용하기 8편 : 실시간 얼굴인식 카메라 | 실시간 카메라 영상에서 사람 얼굴 판별하기 9편 : 실시간 얼굴인식 카메라 | OpenCV Haar feature-based cascade classifiers 사용하기 10편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 데이터 수집 11편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 학습 12편

Naver Blog

8편 : 실시간 얼굴인식 카메라 | 실시간 카메라 영상에서 사람 얼굴 판별하기

실시간 얼굴인식 카메라 | 실시간 카메라 영상에서 사람 얼굴 판별하기 프로젝트 목차 0편 : 개요 1편 : 라즈베리 파이에 라즈비안(OS) 설치(키보드, 마우스, 모니터 없이 설치) 2편 : VNC 뷰어로 라즈베리 파이 원격 제어 3편 : 라즈베리 파이 기본 설정해주기 4편 : 라즈베리 파이 한글 설정 5편 : 라즈베리 파이 카메라 사용하기 6편 : 라즈베리 파이에 OpenCV 설치하기 7편 : 실시간 얼굴인식 카메라 | 파이썬(python)으로 라즈베리 파이 카메라 사용하기 8편 : 실시간 얼굴인식 카메라 | 실시간 카메라 영상에서 사람 얼굴 판별하기 9편 : 실시간 얼굴인식 카메라 | OpenCV Haar feature-based cascade classifiers 사용하기 10편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 데이터 수집 11편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 학습 12편 : 실시간

Naver Blog

9편 : 실시간 얼굴인식 카메라 | OpenCV Haar feature-based cascade classifiers 사용하기

실시간 얼굴인식 카메라 | OpenCV Haar feature-based cascade classifiers 사용하기 프로젝트 목차 0편 : 개요 1편 : 라즈베리 파이에 라즈비안(OS) 설치(키보드, 마우스, 모니터 없이 설치) 2편 : VNC 뷰어로 라즈베리 파이 원격 제어 3편 : 라즈베리 파이 기본 설정해주기 4편 : 라즈베리 파이 한글 설정 5편 : 라즈베리 파이 카메라 사용하기 6편 : 라즈베리 파이에 OpenCV 설치하기 7편 : 실시간 얼굴인식 카메라 | 파이썬(python)으로 라즈베리 파이 카메라 사용하기 8편 : 실시간 얼굴인식 카메라 | 실시간 카메라 영상에서 사람 얼굴 판별하기 9편 : 실시간 얼굴인식 카메라 | OpenCV Haar feature-based cascade classifiers 사용하기 10편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 데이터 수집 11편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜

Naver Blog

10편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 데이터 수집

실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 데이터 수집 프로젝트 목차 0편 : 개요 1편 : 라즈베리 파이에 라즈비안(OS) 설치(키보드, 마우스, 모니터 없이 설치) 2편 : VNC 뷰어로 라즈베리 파이 원격 제어 3편 : 라즈베리 파이 기본 설정해주기 4편 : 라즈베리 파이 한글 설정 5편 : 라즈베리 파이 카메라 사용하기 6편 : 라즈베리 파이에 OpenCV 설치하기 7편 : 실시간 얼굴인식 카메라 | 파이썬(python)으로 라즈베리 파이 카메라 사용하기 8편 : 실시간 얼굴인식 카메라 | 실시간 카메라 영상에서 사람 얼굴 판별하기 9편 : 실시간 얼굴인식 카메라 | OpenCV Haar feature-based cascade classifiers 사용하기 10편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 데이터 수집 11편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 학습

Naver Blog

11편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 학습

실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 학습 프로젝트 목차 0편 : 개요 1편 : 라즈베리 파이에 라즈비안(OS) 설치(키보드, 마우스, 모니터 없이 설치) 2편 : VNC 뷰어로 라즈베리 파이 원격 제어 3편 : 라즈베리 파이 기본 설정해주기 4편 : 라즈베리 파이 한글 설정 5편 : 라즈베리 파이 카메라 사용하기 6편 : 라즈베리 파이에 OpenCV 설치하기 7편 : 실시간 얼굴인식 카메라 | 파이썬(python)으로 라즈베리 파이 카메라 사용하기 8편 : 실시간 얼굴인식 카메라 | 실시간 카메라 영상에서 사람 얼굴 판별하기 9편 : 실시간 얼굴인식 카메라 | OpenCV Haar feature-based cascade classifiers 사용하기 10편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 데이터 수집 11편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 학습 12편

Naver Blog

12편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 인식(최종편)

실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 인식(최종편) 프로젝트 목차 0편 : 개요 1편 : 라즈베리 파이에 라즈비안(OS) 설치(키보드, 마우스, 모니터 없이 설치) 2편 : VNC 뷰어로 라즈베리 파이 원격 제어 3편 : 라즈베리 파이 기본 설정해주기 4편 : 라즈베리 파이 한글 설정 5편 : 라즈베리 파이 카메라 사용하기 6편 : 라즈베리 파이에 OpenCV 설치하기 7편 : 실시간 얼굴인식 카메라 | 파이썬(python)으로 라즈베리 파이 카메라 사용하기 8편 : 실시간 얼굴인식 카메라 | 실시간 카메라 영상에서 사람 얼굴 판별하기 9편 : 실시간 얼굴인식 카메라 | OpenCV Haar feature-based cascade classifiers 사용하기 10편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 데이터 수집 11편 : 실시간 얼굴인식 카메라 | 개인의 얼굴을 학습시켜 각 사람별로 구별하기 | 학습

Naver Blog

마이크로소프트 FACE API 사용법 | 개요

19년도 겨울방학 알고리즘 특강을 들으러 삼성 SDS에 갔다가 우연히 보게 된 광고 디스플레이.. 개인적으로는 이미 OpenCV(haar)를 통하여 얼굴 검출을 해본 적이 있기 때문에 크게 관심을 가지고 보게 되었다. 그러던 중 이미지에서 단순히 사람을 인식하는 것뿐만 아니라 나이, 성별까지 판별하는 것에 놀랐기 때문에 그쪽으로(?) 더 알아보게 되었다. 먼저 이미 다루어보았던 Github의 OpenCV를 확인해보았지만, haar 외의 기법으로 얼굴을 검출하는 코드는 존재했지만, 그것뿐이고 그 이상의 기능은 존재하지 않는듯했다. 그래서 다른 경로를 알아보던 중 마이크로소프트에서 FACE API라는 얼굴 검출 API를 지원한다는 사실을 알게 되었다. 이 API는 얼굴 검출뿐만 아니라 해당 얼굴에서 나이, 성별, 안경 여부, 화장 여부 등의 다양한 정보까지 알 수 있는 API였기 때문에 한번 사용해보고 싶다는 생각이 들었고, 그 과정을 이 블로그에서도 소개해보고자 한다.

Naver Blog

1편 : 마이크로소프트 Azure 및 Cognitive Services 계정 생성

이 글은 아래 마이크로소프트사의 매뉴얼을 토대로 작성되었으며 해당 링크를 통해 진행하여도 무방함. Azure Portal에서 Cognitive Services 계정 만들기 Azure Portal에서 Microsoft Cognitive Services API를 만드는 방법입니다. docs.microsoft.com 지금 Azure 체험 계정 만들기 | Microsoft Azure 12개월 체험 서비스 및 200 USD 크레딧으로 시작하세요. Microsoft Azure에서 지금 체험 계정을 만들어 보세요. azure.microsoft.com 먼저 위 링크를 통해 Azure 체험 계정을 만들어주자. 그냥 마이크로소프트 계정으로 로그인해주면 된다. * 체험 계정이란 말이 좀 생소한데, AWS의 free 티어와 비슷하다고 보면 된다. 1년간 무료로 Azure를 체험할 수 있는 계정이라는 뜻이다. 체험 계정 만들기 선택 Microsoft Azure에 로그인 로그인 Microsoft Azure(

Naver Blog

2편 : 이미지에서 얼굴 감지(인식) 및 나이, 성별 등의 정보 추출하기

빠른 시작: Python SDK를 사용하여 이미지에서 얼굴 감지 및 포착 - Azure Cognitive Services 이 빠른 시작에서는 Face API를 사용하여 원격 이미지에서 얼굴을 감지하고 포착하는 간단한 Python 스크립트를 만들 것입니다. docs.microsoft.com 이 글에서는 위 링크(마이크로소프트사의 튜토리얼)의 내용을 기반으로 작성되었으므로 해당 링크를 보고 진행해도 무방함. 이 글을 진행하기 앞서 아래의 2가지 조건이 이미 선행되어 있어야 한다. 1. Azure 체험 계정이 존재해야 함. 2. Cognitive Services 계정이 존재해야 함. 위의 2가지 조건을 모두 만족하지 않았다면 이전 글을 읽어보기 바란다. 프로젝트를 진행하기 앞서 홈 디렉터리 아래에 MSFACE 디렉터리를 생성해주자. mkdir MSFACE && cd MSFACE FACE API를 사용하기 위해서는 cognitive_face 모듈을 설치해주자. sudo pip3 instal

Naver Blog

포인터 (pointers)

C 언어에서는 어떤 타입 T에 대해서 T의 포인터 타입이 존재한다. 포인터 타입의 실제 값은 메모리의 주소가 된다. 포인터 타입에 사용되는 두 가지 중요한 연산자는 아래와 같다. & : 주소 연산자 * : 역참조(간접 지시) 연산자 다음과 같이 선언한다면 a는 정수 변수이고, p는 정수에 대한 포인터이다. 다음과 같이 하면 &a는 a의 주소를 돌려주어 그 값을 p의 값으로 지정한다. a에 값을 저장하기 위해서는 다음과 같이 할 수 있다. 두 경우 모두 변수 a의 값으로 정수 값이 저장된다. 오른쪽의 경우(*p)는 이 포인터에 100을 저장하는 것이 아니라, 포인터 p가 가리키는 장소에 100을 저장하는 역참조(dereference)를 나타낸다. 추가적인 포인터의 특징 한 포인터가 다른 포인터 변수를 가리키도록 설정할 수 있다. 포인터는 음이 아닌 정수 값을 가지므로 C에서는 포인터에 대한 사칙연산이 가능하다. 포인터들의 크기를 비교할 수 있으며 포인터 값을 정수 값으로 바꿀 수도 있

Naver Blog

동적 메모리 할당(malloc)

프로그램을 작성할 당시에는 얼마나 많은 공간이 필요한지 알 수도 없고, 또 사용되지 않을지도 모르는 아주 큰 공간을 미리 할당해놓는 것은 비효율적일 것이다. C언어에서는 새로운 메모리 공간이 필요할 때마다 함수 malloc을 호출해서 필요한 양의 공간을 요구할 수 있다. 만일 공간을 사용할 수 있으면 요구한 크기의 메모리 영역에 대한 시작 주소에 대한 포인터를 반환한다. 요구한 메모리를 사용할 수 없으면 NULL 포인터가 반환된다. 나중에 메모리 영역이 더 이상 필요 없게 되면 free라는 또 다른 함수 호출을 통하여 그 영역을 시스템에 반환할 수 있다. 일단 메모리 영역이 반환되면 이것을 그 프로그램에서 다시 사용할 수 없다. 다음과 같이 하면 malloc 함수는 적절한 크기(sizeof(int))의 메모리 영역에 대한 첫 번째 주소를 가리키는 포인터를 돌려준다. 여기에 다음과 같은 타입 변환식을 추가해주자. malloc 함수가 메모리 영역의 첫 번째 주소를 가리키는 포인터를 돌려

Naver Blog

동적 메모리 할당(malloc) 예외 처리

malloc 을 호출하여 동적 메모리 영역을 할당하려고 했지만, 메모리의 부족으로 실패할 가능성이 있을 것이다. 먼저, malloc 호출이 실패한 것을 어떻게 알 수 있을까? malloc 함수는 메모리를 사용할 수 없으면 NULL 포인터를 반환한다. malloc 함수의 반환 값을 어떤 포인터에 지정한 뒤, 해당 포인터가 주소 값이 아닌 NULL 포인터를 가지고 있다면 malloc 호출이 실패한 것을 알 수 있을 것이다. 다음과 같이 if 조건문을 통해 쉽게 확인할 수 있다. 다음과 같이 메모리 할당이 실패한다면 프로그램을 종료시킬 수도 있다. #include <stdio.h> #include <stdlib.h> //exit 호출을 위한 헤더 선언 int main(){ int I, *pInt; //정수 변수 I, 정수 포인터 pInt float F, *pFloat; //실수 변수 F, 실수 포인터 pFloat //메모리 부족으로 malloc 호출이 실패한다면 프로그램 종료 if ((p

Naver Blog

동적 메모리 할당(malloc)의 매크로 정의, 허상 참조(dangling reference)

malloc은 프로그램의 여러 곳에서부터 호출되기 때문에 malloc 을 기동시키고, malloc이 실패할 때 빠져나가는 매크로를 정의하는 것이 편리할 때가 있다. 다음과 같이 포인터와 자료형의 크기를 입력받아 malloc을 호출하고, 메모리 할당에 실패한다면 프로그램을 종료하는 매크로를 작성할 수 있다. // blog.naver.com/ljy9378 // Copyright by 로졔 2019 #include <stdio.h> #include <stdlib.h> //exit 호출을 위한 헤더 선언 #define MALLOC(p,s) \ // 포인터 p, 자료형의 크기 s if ((p = malloc(s) == NULL) { \ fprintf(stderr, "Insufficient memory"); \ exit(EXIT_FAILURE); \ } int main(){ int I, *pInt; //정수 변수 I, 정수 포인터 pInt float F, *pFloat; //실수 변수 F, 실

Naver Blog

포인터의 위험성

C 프로그래밍을 할 때 포인터가 실제로 어떤 대상을 가리키고 있지 않을 때는 값을 전부 NULL로 설정하는 것이 바람직하다. 이것으로 프로그램 범위 밖이나 합당하지 않은 메모리 영역을 참조할 가능성이 적어진다. NULL이 아닌 0으로 설정하는 경우, 어떤 컴퓨터에서는 NULL을 돌려주어 프로그램이 계속 실행될 수 있지만, 어떤 컴퓨터에서는 메모리 0 위치에 있는 비트들을 그대로 돌려주어 심각한 오류를 발생시킨다. 또 다른 유용한 프로그래밍 기법은 포인터 타입 간의 변환을 할 때 명시적인 타입 변환(type cast)을 하는 것이다. 다음과 같이 한다면 부동 소수에 대한 포인터 pF에 정수에 대한 포인터 pI를 지정하게 된다. 내가 사용하는 Dev c++ 환경에서 위 코드를 컴파일하면 다음과 같은 경고가 출력된다. 포인터의 타입이 다르다 다음과 같이 명시적으로 타입 변환을 해주는 것이 좋다. 타입 변환 많은 시스템에서 포인터의 크기는 int 타입의 크기와 같다. 또 int는 디폴트 타

Naver Blog

이원 탐색(binary search), 이진 탐색, 매크로

n ≥ 1개의 서로 다른 정수가 이미 정렬되어 배열 arr에 저장되어 있다고 가정하자. 정수 target이 배열 arr에 있는가를 검사하려고 한다. 만일 존재한다면 arr[i] = target인 인덱스 i를 반환하고, 그렇지 않다면 -1을 반환한다. 배열 arr이 정렬되어 있기 때문에 다음과 같은 방법을 사용할 수 있다. left, right는 탐색하고자 하는 배열의 왼쪽, 오른쪽 끝 지점을 가리킨다. 초기 값으로 left=0, right=n-1로 하고 중간 위치를 mid로 설정하여 arr[mid]와 target을 비교하여 다음과 같은 세 가지 경우 중 하나를 고려할 수 있다. 1) target < arr[mid] : 이 경우 target은 arr[0]과 arr[mid-1] 사이에 존재하므로 right을 mid-1로 설정한다. 2) target = arr[mid] : 이 경우는 mid를 반환한다. 3) target > arr[mid] : 이 경우 target은 arr[mid+1]과

Naver Blog

순환(재귀) 알고리즘, 이진(이원) 탐색

대부분의 전산학도들은 순환 기법을 Ackermann 함수나 factorial 연산 같은 특수한 부류의 문제에만 유용하다고 생각하는데, 이는 옳지 않다. 왜냐하면 지정문, if-else, while 문으로 작성할 수 있는 어떤 프로그램도 순환(재귀)으로 작성할 수 있기 때문이다. 때때로 이 순환 함수가 반복 함수보다 이해하기 쉬운 경우도 있다. 앞선 글에서 다루어보았던 이원 탐색 프로그램을 순환 방식으로 변환하기 위해서는 1) 순환 호출이 종결될 수 있도록 경계 조건들을 먼저 설정해야 하며, 2) 매 호출마다 해답을 향해 한 단계씩 가까워지게끔 순환 호출을 구현하여야 한다. #define COMPARE(x,y) (((x) < (y)) ? -1: ((x) == (y)) ? 0 : 1) int binarySearch(int arr[], int target, int left, int right){ int mid; if (left <= right){ mid = (left + right) /

Naver Blog

재귀 알고리즘, 순열(permutation) 나열하기

n ≥1 개의 원소를 가진 집합이 주어졌을 때 이 집합의 모든 가능한 순열을 출력해보자. n 개의 주어진 원소에 대해 n! 개의 상이한 순열이 있음도 쉽게 알 수 있다. 4개의 원소 { a, b, c, d }로 된 집합을 살펴보면 간단한 알고리즘을 얻을 수 있다. 이에 대한 순열의 집합은 다음과 같이 출력시키면 결과를 얻을 수 있다. 1) a로 시작하는 { b, c, d }의 모든 순열 2) b로 시작하는 { a, c, d }의 모든 순열 3) c로 시작하는 { a, b, d }의 모든 순열 4) d로 시작하는 { a, b, c }의 모든 순열 ' ~로 시작하는 ~의 모든 순열 '이라는 표현이 바로 순열의 실마리이다. 이것은 n-1개의 원소에 동작하는 알고리즘이 있다면, n 개의 원소를 가진 집합에 대한 문제도 해결할 수 있음을 의미한다. 이러한 사고로부터 다음과 같은 프로그램을 만들 수 있다. 초기의 함수 호출은 permutation(arr, 0, n-1)이 된다. #define

Naver Blog

재귀 알고리즘, nPk, 순열 사전 순서대로 나열하기

앞선 글에서 보았던 순열 나열하기 알고리즘은 매우 단순하다는 장점은 있지만, 사전 순서가 아니라는 단점이 있다. 하지만 우리가 순열을 나열하게 되는 경우에는 사전 순서로 나열해야 하는 경우가 많을 것이다. 또한 nPn을 나열하는 경우 외에도 nPk를 나열해야 하는 경우도 상당히 많다. 먼저 n 개의 원소 중 k 개의 원소를 나열하는 경우에는 다음과 같이 그저 변수 k를 추가하고 그냥 k 개의 원소를 출력해주기만 하면 된다. nPn과 크게 다르지 않은 부분이다. void permutation(char arr[], int i, int n, int k){ int j, temp; if (i == k){ //깊이가 k가 되면 for(j=0; j<k; j++) printf("%c", arr[j]); //k개의 원소만 출력해준다. printf("\n"); return; } for(j=i; j<=n; j++){ SWAP(arr[i], arr[j], temp); permutation(arr, i+1

Naver Blog

데이터 추상화

C 언어에는 기본 데이터 타입들로 char, int, float, double 등이 있다. 이러한 데이터 타입 중 어떤 것은 키워드인 short, long, unsigned에 의해 변경될 수 있다. 궁극적으로는 우리가 다루려는 실세계의 추상화는 이러한 데이터 타입들을 통해 표현되어야 한다. 이러한 기본형에 대해 C 언어는 자료를 함께 그룹화하는 두 가지 기법으로 배열(array)과 구조(structure)를 제공한다. 배열은 동일한 기본 데이터 타입에 속하는 원소의 집합이다. 이것은 묵시적으로 선언되는데, 예를 들어 int arr[5]는 5개의 원소를 갖는 정수 타입 배열을 정의하며 철자는 0~4 범위 내에서는 정당하다. 구조는 원소의 데이터 타입이 반드시 같을 필요가 없는 원소들의 집합으로 명시적으로 정의된다. 예를 들어 아래와 같은 경우는 struct { int id; char name, grade; } student; 1 개의 정수 타입과 2개의 문자 타입인 3개의 필드를 갖는

Naver Blog

점근 표기법(Ο, Ω, Θ)

한 프로그램의 시간과 공간 복잡도에 대한 의미 있느(그러나 정확하지는 않은) 명령문을 만들 수 있게 해주는 용어를 소개하겠다. 지금부터 제시되는 함수 f와 g는 음수 값을 가지지 않는 함수들이다. Ο(빅 오)의 정의 모든 n, n ≥ ni에 대해 f(n) ≤ cg(n)인 조건을 만족하는 두 양의 상수 c와 ni가 존재하기만 하면 f(n) = Ο(g(n))이다. (단, f(n) = Ο(g(n))과 Ο(g(n)) = f(n)이 동일하지는 않다. 여기의 기호 '='은 '동등하다'가 아니라 '~이다'라고 해석해야 한다.) 예를 들어 Ο(n^2)이라고 한다면 이는 최고차항이 n^2보다 크지 않은 함수를 말한다. f(n) = Ο(g(n))이 의미상으로 유익하기 위해서는 g(n)은 f(n) = Ο(g(n))이 되도록 가능한 한 작아야 한다. 연산 시간이 상수인 것을 의미할 때 Ο(1)이라 쓴다. Ο(n)은 선형이라 하고, Ο(n^2)은 평방형, Ο(n^3)은 입방형, 그리고 Ο(2^n)은 지수형

Naver Blog

배열(array)

대부분의 프로그래머들은 배열을 단지 '일련의 연속적인 메모리 위치'로 보고 있지만 이는 배열을 단지 구현의 측면에서만 강조함으로써 생긴 경과로, 올바르지 못하다. 물론 배열이 일련의 연속적인 메모리 위치로 구현되는 것이 보통이지만 반드시 그런 것도 아니다. 직설적으로 표현하면 배열은 인덱스와 값 <index, value>의 쌍으로 구성된 집합으로서, 정의된 각 인덱스는 그 인덱스와 관련된 값을 갖는다. 수학 용어로 이것을 대응(correspondence) 또는 사상(mapping)이라 부른다. 먼저 1차원 배열만을 생각해보자. C에서 1차원 배열은 변수의 이름 끝에 대괄호를 추가하여 묵시적으로 선언한다. 다음 코드의 선언을 보자. 위 선언은 각각 5개의 원소를 포함하는 두 배열을 선언한 것이다. 첫 번째 배열(Arr)은 5개의 정수를 정의한 반면, 두 번째 배열(pArr)은 정수에 대한 5개의 포인터를 정의한다. C언어에서 모든 배열은 인덱스 0에서 시작하기 때문에 Arr[0], A

Naver Blog

배열(array), 1차원 배열의 주소 계산

다음 코드를 살펴보자. #include <stdio.h> float Input[100], ans; float sum(float arr[], int n){ int i; float ret = 0; //sum 함수 안에서 배열 arr의 크기를 알아낼 수는 없다. //따라서 크기 n을 매개변수로 넘겨주거나 전역변수로 접근해야 한다. for(i=0; i<n; i++) ret += arr[i]; return ret; } int main(){ int i; for(i=0; i<100; i++) Input[i]=i; ans = sum(Input, 100); printf("The sum is : %f\n", ans); } sum이 호출되면 Input = &Input[0]은 임시 장소에 복사되고 형식 매개변수 arr과 연결된다. arr[i]가 기호 "=" 오른 편에 나오면 역참조가 일어나서 'arr + i'가 가리키는 값이 반환된다. 만일 arri[]가 기호 "="의 왼편에 나타난다면, 오른 편에서 생

Naver Blog

동적 배열(dynamic array), 1차원 동적 배열

위 선언에서는 상수 MAXN을 100으로 정의하였다. 그 결과, 이 프로그램은 100개까지의 정수를 정렬하는 데 사용될 수 있다. 만일 100개보다 많은 수를 정렬하려 한다면, MAXN의 정의를 어떤 큰 값으로 변경하고 프로그램을 다시 컴파일해야된다. 이 새로운 값은 얼마나 커야 될까? 만일 MAXN을 아주 큰 수로 설정한다면 n의 입력 값이 MAXN의 값을 초과할 가능성이 적을 것이기 때문에 프로그램이 실패할 수 있는 여지를 감소시키게 된다. 그러나 배열 Arr을 위한 메모리가 부족해서 프로그램을 컴파일하지 못하는 가능성을 증가시키게 된다. 프로그램을 작성할 때 종종 사용할 배열의 크기를 결정하기에 아주 곤란한 경우에 처하는 때가 있다. 이에 대한 좋은 해답은, 이 결정을 미루었다가 필요한 배열 크기의 적당한 추정치가 나올 때 배열을 할당하는 것이다. 예를 들어 다음과 같이 할 수 있다. #include <stdio.h> #include <stdlib.h> #define MALLO

Naver Blog

동적 배열(dynamic array), 2차원 동적 배열

C 언어는 다차원 배열을 표현하기 위하여 소위 배열의 배열을 사용하고 있다. 2차원 배열은 각 원소 자체가 1차원 배열이 되는 1차원 배열로 표현된다. 2차원 배열을 표현하기 위하여 라고 하면 실제로 길이가 3인 1차원 배열 Arr이 생성되는데, 이 Arr의 각 원소는 길이가 5인 1차원 배열이다. C는 원소 Arr[i][j]를 찾을 때 제일 먼저 Arr[i]에 있는 포인터에 접근한다. 이 포인터는 배열의 행 i의 0번째 원소의 메모리 주소를 제공한다. 그러면 이 포인터에 j*sizeof(int)를 더하면 Arr[i][j]의 주소가 결정된다. 다음은 2차원 배열을 생성하는 코드이다. //rows*cols의 2차원 배열을 생성하는 함수. int **make2D(int rows, int cols){ int **array, i; //row 포인터들에 메모리 주소를 할당. MALLOC(array, rows*sizeof(*array)); //각 row마다 col만큼의 메모리 할당. for(i

Naver Blog

동적 메모리 할당 후 초기화(calloc)

C는 malloc 외에도 추가적으로 메모리 할당 함수 calloc을 제공하는데 이 함수는 동적 할당 배열을 다루는 데 아주 유용하다. 함수 calloc은 사용자가 지정한 양의 메모리를 할당하고 할당된 메모리를 0으로 초기화한다.(즉, 할당된 비트를 모두 0으로 설정) 그리고 할당된 메모리의 시작에 대한 포인터를 반환하며 메모리가 충분하지 않는 경우에 반환되는 값은 NULL이다. malloc과 마찬가지로 다음과 같은 매크로를 작성하여 사용할 수 있다. // calloc 호출, 실패 시 프로그램 종료 // 포인터 p, 배열의 크기 n, 자료형의 크기 s #define CALLOC(p,n,s) \ if (!(p = calloc(n,s))) { \ fprintf(stderr, "Insufficient memory"); \ exit(EXIT_FAILURE); \ } 다음 소스코드는 calloc으로 배열에 동적 메모리를 할당하고, 그 주소와 값을 확인하는 코드이다. #include <stdio

Naver Blog

[음식] 영등포 타임스퀘어 르사이공

오랜만에 주말이 동생에 쉬는 날이어서 같이 점심을 먹으러 나가보았다. 원래 가보려 했던 곳은 타임스퀘어 안에 있는 식당이 아니고 근처에 있는 다른 베트남 식당을 가보려고 했었는데, 오늘 문을 열지 않아서 어쩔 수 없이 타임스퀘어 안으로 들어갔다.. 타임스퀘어 안에서 어떤 식당에서 점심을 먹을까 고민하던 중 베트남 식당이 있길래 들어가 보았다. Previous image Next image 2명이서 쌀국수 하나, 분짜 하나, 해물볶음밥 하나를 시켰다. 나는 쌀국수를 먹었는데 일단 국물은 소고기 향이 진하게 나서 좋았고 고수 향도 한국 식당 치고는 좀 많이 났다.(나는 고수를 워낙 잘먹기 때문에 전혀 신경을 안썼다) 소고기는 사진에서 보이듯이 상당히 많이 들어있었는데 상당히 얇게 찢어져 있어서 먹기 좋았다. 개인적으로 딱 내 취향에 맞는 쌀국수였다. 동생이 분짜를 먹었는데 고기는 마트에서 파는 돼지갈비랑 비슷하고, 완자는 동그랑땡과 비슷하다고 한다.(근데 그게 베트남 현지 맛이라고 함.

Naver Blog

구조(struct)

배열은 같은 타입의 데이터의 모임이다. C 언어에서는 타입이 다른 데이터를 그룹화하는 다른 방법이 있으며, 이를 구조(structure)라 하고 struct라고 표기한다. 구조는 데이터 항목의 집단으로서, 각 항목은 타입과 이름으로 식별된다. 예를 들어, 다음과 같은 선언은 이름이 person이고 다음 3개의 필드를 갖는 변수를 생성한다. * 문자 배열로 된 이름(name) * person의 나이(age)를 나타내는 정수 값 * 각 개인의 월급(salary)을 나타내는 float 값 이러한 필드에 아래와 같이 값을 할당할 수 있다. 구조의 멤버 연산자로서 '.'을 사용하고 있음에 유의하라. 이 연산자는 구조 내에서 특정 멤버를 선택하는 데 사용한다. 다음과 같이 typedef 명령문을 사용하여 구조 데이터 타입을 생성할 수 있다. human은 구조의 정의를 통해 정의된 타입 이름이며, 이후 다음과 같이 변수를 선언할 수 있다. 만일 1)if(person1==person2)라고 표기하

Naver Blog

유니언(union)

앞에서 살펴본 구조 human에서 성별을 구별한다고 가정하자. 그래서 남성의 경우 수염을 기르는지 여부를, 여성의 경우 출산 아동의 수를 각각 파악한다고 하자. 이런 경우를 위해 C 언어에서는 유니언(union)이라는 것을 제공한다. union의 선언은 구조와 유사하지만 union의 필드들은 그들의 메모리 공간을 공용해야 한다. 이는 어느 시점에서 union의 한 필드만 활성화 되어 사용 가능하다는 것을 의미한다. 다음과 같이 person1과 person2에 값을 할당할 수 있다. 먼저 태그(tag) 필드에 값을 설정한 점에 유의하라. 이 값은 union에 있는 필드의 활성화를 결정한다. 이후 union의 적절한 필드에 값을 지정한다. 예를 들어, 만일 sexInfo.sex의 값이 male이면 sexInfo.uni.beard에 값을 넣는다. 마찬가지로 female인 경우 sexInfo.uni.children 필드에 값을 지정한다. C 언어는 union에서 필드를 올바르게 사용했는지의

Naver Blog

자기 참조 구조(self-referential structure)

자기 참조 구조는 구성 요소 중에 자기 자신을 가리키는 포인터가 1개 이상 존재하는 구조를 말한다. 다음 예를 생각해보자. 구조 list의 각 인스턴스는 data와 link의 두 구성 요소를 가지고 있다. data는 하나의 문자이고 link는 list 구조에 대한 포인터이다. link의 값은 list의 한 인스턴스의 메모리 주소이거나 NULL 포인터이다. 다음과 같이 구조를 생성하고 이들의 각 필드에 값을 지정해 줄 수 있다. link 필드를 다른 구조를 가리키는 포인터로 대체하여 이 구조들을 서로 연결할 수 있다. lozenia64/DataStructuers C로 쓴 자료구조론. Contribute to lozenia64/DataStructuers development by creating an account on GitHub. github.com

Naver Blog

스택(stack)

스택은 탑(top)이라고 하는 한쪽 끝에서 모든 삽입(push)과 삭제(pop)가 일어나는 순서 리스트이다. 스택에서는 제일 마지막으로 삽입된 원소가 제일 먼저 삭제되기 때문에 후입선출(LIFO, Last In First Out) 리스트라고도 한다. 스택을 구현하는 가장 쉬운 방법은 1 차원 배열 stack[MAXSIZE]를 사용하는 것인데, 여기서 MAXSIZE는 허용할 수 있는 스택의 최대 크기이다. 스택의 첫 번째 원소, 즉 최하위 원소는 stack[0]에 저장되고, 두 번째 원소는 stack[1], 그리고 i 번째 원소는 stack[i-1]에 저장된다. 변수 top은 스택의 최상위 원소를 가리킨다. 초기에 top은 -1의 값을 가지며 이는 공백 스택을 나타낸다. 다음의 예에서는 element라는 하나의 key 필드 만을 가지는 구조를 사용하지만, 이는 예를 들기 위한 것일 뿐 일반적으로 하나의 필드만을 갖는 구조는 생성하지 않는다. 변수 top과 상수 MAXSIZE를 사용하면

Naver Blog

[삼성 SDS 멘토링] 삼성 SDS 프로그래밍 멘토링 후기

2월 26일 화요일 삼성 SDS 프로그래밍 멘토링을 다녀왔다. 삼성 SDS의 소셜 팬들을 대상으로 하는 멘토링으로 SDS 페이스북 페이지에 좋아요를 누른 대학생이라면 누구나 참여 가능하다. 신청은 2월 초부터 진행되었으며 나도 좋은 기회인듯싶어 창우 형 및 학교 지인들과 함께 신청해두었었다. 사실 경쟁률이 치열해 가지 못할까 봐 걱정했는데 다행히 나뿐 아니라 신청한 주변인들도 모두 갈 수 있었다. 멘토링 시간은 오후 3시~6시였지만, 2시부터 출석체크가 가능하며 일찍 온 사람들을 대상으로 얼리버드 이벤트가 진행될 예정이라고 하길래 한번 2시에 딱 맞춰 일찍 가보는 것도 좋겠다는 생각이 들었다. 창우형, 현석이와 1시 50분에 잠실역에서 만나서 바로 갔는데.. 이미 얼리버드 이벤트는 종료되어있었다. 얼리버드 이벤트는 선착순으로 온 사람들에게 스타벅스 기프티콘, 만년필 등의 선물을 증정했는데 내가 갔을 때 약 80명(여기서 심각하게 놀람) 이상이 먼저 들어가 있다는 말을 들었다. 다행히

Naver Blog

[SW Vision Tour] 삼성전자(CE/IM 부문) SW Vision Tour 후기

엊그제 삼성 SDS에 멘토링을 참석한 뒤에 어제(2월 27일 수용일)는 삼성전자 CE/IM에서 주관하는 SW Vision Tour를 다녀왔다. 이번에는 오전 11시에 영통역에서 셔틀을 제공했기 때문에 조금 일찍 도착할 정도로 출발했다. 10시 40분쯤 영통역에 도착하니 버스가 한 5개 정도 대기하고 있었으며 사람들이 도착하는 순서대로 버스에 바로 탑승하고 가득 찬 버스는 회사로 바로 출발하는 방식이었다. 일찍 도착한 사람들이 밖에서 기다릴 필요가 없도록 배려한 점이 아주 마음에 들었다. 11시쯤 삼성 Digital City에 들어가서 C-LAB으로 사용된다는 홀에 들어가게 되었다. 다과와 음료가 상당히 많이 준비되어 있어서 원하는 대로 먹을 수 있도록 되어있었다. 음료는 커피, 과일 주스 등이 있었고 상당한 종류와 양의 쿠키, 초콜릿 등이 있어서 종류별로 먹어봤다. 특이할 만한 점은 일회용품의 사용을 줄이기 위하여 일회용 컵 없이 머그잔이나 플라스틱 컵을 준비해 둔 점이었다.(나중에

Naver Blog

이미 동적 할당된 메모리 재조정(realloc)

함수 realloc은 malloc이나 calloc으로 이미 할당된 메모리 크기를 재조정한다. 예를 들어 다음 명령문은 포인터 Arr이 가리키는 메모리 블록의 크기를 sizeof(int)*n으로 변경한다. realloc이 크기 조정을 할 수 있을 때는 새로운 블록의 시작에 대한 포인터를 반환하고, 크기 조정을 할 수 없을 때는 원래 블록은 변경되지 않고 함수는 NULL 값을 반환한다. malloc, calloc에서와 같이 매크로 REALLOC을 정의할 수 있다. lozenia64/DataStructuers C로 쓴 자료구조론. Contribute to lozenia64/DataStructuers development by creating an account on GitHub. github.com

Naver Blog

동적 배열을 사용하는 스택

이전 글에서 설명한 스택 구현의 단점은 스택이 얼마나 크게 될지 그 범위(MAXSIZE)를 미리 알아야 된다는 것이다. 이 단점은 동적으로 할당된 배열을 이용하고 필요할 때 이 배열의 크기를 증대시킴으로써 극복할 수 있다. 스택이 비는 경우와 스택이 가득 차는 경우 중, 스택이 비는 경우는 top == -1로 기존과 같다. 따라서 함수 pop은 수정할 필요가 없다. 하지만 함수 push의 코드는 변경해 주어야 한다. 기존에는 에러 메시지를 출력하고 프로그램을 종료했다면, 새로운 코드는 배열 stack의 크기를 확장시켜서 스택에 원소를 추가로 삽입할 수 있도록 한다. 이때 배열의 크기를 확장시키기 전에 새로운 크기를 결정해야 된다. 배열 배가(array doubling)에서는 배열의 크기를 늘릴 필요가 있을 때는 항상 배열 크기를 2배로 만든다. lozenia64/DataStructuers C로 쓴 자료구조론. Contribute to lozenia64/DataStructuers de

Naver Blog

C 언어로 C++ STL vector 구현(push_back)

이전 글(동적 배열을 사용하는 스택)을 읽은 사람들 중 상당수는 C++의 STL vector와의 유사성을 느꼈을 것이라고 생각한다. C++의 vector는 동적 배열을 사용하며 배열이 가득 찰 때마다 배열의 크기를 1.5배 혹은 2배(컴파일러마다 다름) 씩 늘려주는 방식으로 구현되어있다고 한다. 이번 글에서는 malloc, realloc을 사용하여 한번 vector를 구현해 보고자 한다. 이전 글들과 같이 malloc, realloc 함수를 매크로로 정의해주자. STL의 vector가 타입을 가리지 않던 것처럼, 여기서도 그냥 자기가 원하는 타입을 구조로 정의하여 사용해 줄 수 있다. 초기 vector의 크기는 1이며, 현재 원소가 없으므로 vector의 마지막 인덱스는 -1이다. 이제 push_back 함수를 작성해보자. 이 함수는 vector에 여유 공간이 존재하면 vector의 맨 뒤에 원소를 삽입하고, 여유 공간이 없다면 vectorFull() 함수를 호출한다. 당연하겠지만,

Naver Blog

큐(queue), 원형 큐(circular queue)

큐는 한쪽 끝에서 삽입이 일어나고 그 반대쪽 끝에서 삭제가 일어나는 순서 리스트이다. 새로운 원소가 삽입되는 끝을 rear이라 하고 원소가 삭제되는 끝을 front라 한다. 큐에 대한 제약이 의미하는 바는, 만약 원소 A, B, C, D, E를 이 순서대로 큐에 삽입한다면 제일 먼저 삭제되는 원소는 A라는 것이다. 이와 같이 큐에 제일 먼저 삽입된 원소가 제일 먼저 삭제되기 때문에, 이 큐를 선입선출(FIFO, First-In-First-Out) 리스트라고도 한다. 먼저 다음과 같이 큐에 삽입할 구조를 정의해주고, 배열 queue를 선언해 준다. 초기 상태의 배열에는 원소가 존재하지 않으므로, 첫 번째 원소의 인덱스(front)와 마지막 원소의 인덱스(rear)는 모두 -1이다. 이제 함수 addQ와 deleteQ를 구현해보자. queueFull의 구현은 stackFull의 구현과 비슷하다. 합수 addQ와 deleteQ는 구조적으로 스택의 push, pop 함수와 비슷하다. 스택은

Naver Blog

버전 관리란?

버전 관리는 무엇이고 우리는 왜 이것을 알아야 할까? 버전 관리 시스템(VCS, Version Control System)은 파일 변화를 시간에 따라 기록했다가 나중에 특정 시점의 버전을 다시 꺼내올 수 있는 시스템이다. VCS를 사용하면 각 파일을 이전 상태로 되돌릴 수 있고, 프로젝트를 통째로 이전 상태로 되돌릴 수 있고, 시간에 따라 수정 내용을 비교해 볼 수 있고, 누가 문제를 일으켰는지도 추적할 수 있고, 누가 언제 만들어낸 이슈인지도 알 수 있고, 파일을 잃어버리거나 잘못 고쳤을 때도 쉽게 복구할 수 있으며 이 모든 장점들을 큰 노력 없이 이용할 수 있다. 로컬 버전 관리 많은 사람들이 버전을 관리하기 위해 디렉터리로 파일을 복사하는 방법을 쓴다. 이 방법은 간단하므로 자주 사용한다. 그렇지만 정말 뭔가 잘못되기 쉽다. 작업하던 디렉터리를 지워버리거나, 실수로 파일을 잘못 고칠 수도 있고, 잘못 복사할 수도 있다. 이런 이유로 프로그래머들은 오래전에 로컬 VCS라는 걸 만

Naver Blog

소프트웨어 유사도 탐지 시스템 MOSS(Measure Of Software Similarity) 사용법

이번 학기 대학에서 TA를 맡게 되었는데 교수님께서 과제를 채점할 때, MOSS를 사용하라고 하셔서 인터넷으로 사용법을 찾아봤다. 다행히 정리가 잘 된 블로그가 있어서 혼자서도 잘 사용해 볼 수 있었는데, 조금 시행착오가 있어서 여기에 정리해보려고 한다. 막상 써보니 생각보다 성능이 좋은 것 같아서 과제 때마다 학생들이 단체로 걸려서 귀찮게 되지 않을까 짐작해본다.. (해답을 미리 보(듣)더라도 제발 코딩은 스스로 하길..) A System for Detecting Software Similarity http://theory.stanford.edu/~aiken/moss/ MOSS는 현재 stanford 대학에서 서비스하고 있는 소프트웨어 소스코드 유사도 감별 시스템이다. 확인할 수 있는 언어는 C, C++, Java, C#, Python, Visual Basic, Javascript, FORTRAN, ML, Haskell, Lisp, Scheme, Pascal, Modula2, Ad

Naver Blog

Git의 역사/탄생

리눅스(Lunux) 커널은 굉장히 규모가 큰 오픈 소스 프로젝트다. 리눅스 커널은 오랫동안(1991~2002) Patch와 단순 압축 파일로만 관리됐다. 2002년에 드디어 BitKeeper라고 불리는 상용 DVCS를 사용하기 시작했다. 하지만 2005년에 BitKeeper의 회사가 이를 무료로 사용하지 못하게 하면서 관계가 틀어졌으며, 이 사건이 리누스 토발즈가 자체 도구를 만드는 계기가 되었다. Git은 BitKeeper를 사용하면서 배운 교훈을 기초로 아래와 같은 목표를 세웠다. 빠른 속도 단순한 구조 비선형적인 개발(수천 개의 동시다발적인 브랜치) 완벽한 분산 리눅스 커널 같은 대형 프로젝트에도 유용할 것(속도나 데이터 크기 면에서) Pro Git Git은 2005년 탄생하고 나서 아직도 초기 목표를 그대로 유지하고 있다.

Naver Blog

동적 할당 배열을 이용하는 원형 큐

큐 원소를 저장하기 위해 동적 할당 배열을 사용한다고 가정하자. 만원 큐에 원소를 삽입하기 위해서는 먼저 realloc과 같은 함수를 이용해서 배열의 크기를 확장시켜야 한다. 앞서 다루었던 동적 할당 스택에서와 같이 배열 배가 방법을 사용해보자. 그러나 단순히 realloc을 사용해서 배열 크기를 배로 만드는 것으로는 충분치 않다. 다음과 같은 원형 큐를 살펴보자. front=4, rear=3 이전 글(원형 큐)을 보지 않았다면 먼저 보기를 추천하고, 보았더라도 기억나지 않는 사람들을 위해 다시 말하자면, front는 큐의 첫 번째 원소의 한 칸 앞이며, rear는 마지막 원소의 위치이다. 다음 그림은 realloc을 사용하여 2배 확장된 배열을 보여주고 있다. front=4, rear=3 정확한 원형 큐 구조를 얻기 위해서는 다음 그림과 같이 front 이후의 원소들을 배열의 오른쪽 끝으로 밀어주면 된다. front=10, rear=3 하지만 굳이 위의 방법처럼 하지 않더라고 다음

Naver Blog

Git 기초

Git의 핵심은 뭘까? 이 질문은 Git을 이해하는 데 굉장히 중요하다. Git이 무엇이고 어떻게 동작하는지 이해한다면 Git을 쉽고 효과적으로 사용할 수 있다. Git을 배우려면 다른 VCS를 사용하던 경험을 버려야 한다. Git은 미묘하게 달라서 다른 VCS에서 쓰던 개념으로는 헷갈릴 수 있다. 사용자 인터페이스는 매우 비슷하지만, 정보를 취급하는 방식이 다르다. 이런 차이점을 이해하면 Git을 사용하는 것이 어렵지 않다. 차이가 아니라 스냅샷 Subversion이나 그와 비슷한 VCS 들과 Git의 가장 큰 차이점은 데이터를 다루는 방법에 있다. 큰 틀에서 봤을 때 VCS 대부분은 관리하는 정보가 파일들의 목록이다. CVS, Subversion, Perforce, Bazaar 등의 시스템은 각 파일의 변화를 시간순으로 관리하면서 파일들의 집합을 관리한다. 각 파일의 변화를 시간순으로 관리 Git은 이런 식으로 데이터를 저장하지도 취급하지도 않는다. 대신 Git은 데이터를 시스템

Naver Blog

CLI, Git 설치

CLI Git을 사용하는 방법은 많다. CLI(Command Line Interface)로 사용할 수도 있고 GUI를 사용할 수도 있다. 이 글에서는 CLI 사용법을 설명한다. CLI를 사용할 줄 알면 GUI도 사용할 수 있지만 반대는 성립하지 않는다. Git 설치 1. 리눅스에 설치 리눅스에서 패키지로 Git을 설치할 수 있다. 페도라에서는 다음과 같이한다. sudo yum install git 데비안 리눅스에서는 다음과 같이 할 수 있다. sudo apt install git 2. 맥에 설치 Mavericks(10.0)부터는 터미널을 열고 git을 실행하면 바로 시작할 수 있다. 3. 윈도우에 설치 공식 배포판은 Git 웹사이트에서 내려받을 수 있다.

Naver Blog

Git 저장소 만들기 : 기존 디렉터리를 Git 저장소로 만들기

기존 프로젝트를 Git으로 관리하고 싶을 때 프로젝트의 디렉터리로 이동해서 아래와 같은 명령을 사용한다. 이 명령은 .git이라는 하위 디렉터리를 만든다. .git 디렉터리에는 저장소에 필요한 뼈대 파일이 들어있다. 이 명령만으로는 아직 프로젝트의 어떤 파일도 관리하지 않는다. .git 디렉터리 Git 이 파일을 관리하게 하려면 저장소에 파일을 추가하고 커밋 해야 한다. git add 명령으로 파일을 추가하고 git commit 명령으로 커밋 한다. 명령어 몇 개로 순식간에 Git 저장소를 만들고 파일 버전 관리를 시작했다.

Naver Blog

Git 저장소 만들기 : 기존 저장소를 Clone 하기

다른 프로젝트에 참여하려거나(contribute) Git 저장소를 복사하고 싶을 때 git clone 명령을 사용한다. Git이 Subversion과 다른, 가장 큰 차이점은 서버에 있는 거의 모든 데이터를 복사한다는 것이다. git clone을 실행하면 프로젝트 히스토리를 전부 받아온다. 실제로 서버의 디스크가 망가져도 클라이언트 저장소 중에서 아무거나 하나 가져다가 복구하면 된다(서버에만 적용되었던 '설정'은 복구하지 못하지만 모든 '데이터'는 복구가 가능). git clone [url] 명령으로 저장소를 clone 한다. 내가 작성해놓은 C언어 소스코드를 Clone 하려면 아래와 같이 실행한다. 이 명령은 'DataStructuers'라는 디렉터리를 만들고 그 안에 .git 디렉터리를 만든다. 그리고 저장소의 데이터를 모두 가져와서 자동으로 가장 최신 버전을 Checkout 해 놓는다. DataStructures 디렉터리로 이동하면 Checkout으로 생성한 파일을 볼 수 있고

Naver Blog

Git의 워킹 디렉터리 파일들의 라이프사이클

Git의 워킹 디렉터리 파일들의 라이프사이클 이제는 파일을 수정하고 파일의 스냅샷을 커밋 해보자. 파일을 수정하다가 저장하고 싶으면 스냅샷을 커밋 한다. 워킹 디렉터리의 모든 파일은 Tracked와 Untracked로 나뉜다. Tracked 파일은 이미 스냅샷에 포함돼 있던 파일이다. Tracked 파일은 다시 Unmodified, Modified, Staged로 나뉜다. 나머지 파일은 모두 Untracked이다. 처음 저장소를 clone 했을 때는 모든 파일이 Tracked(추적)면서 Unmodifed(수정하지 않음) 상태이다. 아직 아무것도 수정하지 않았기 때문이다. 이 상태에서 어떤 파일을 수정하면 해당 파일은 Modified(수정) 상태가 된다. 커밋을 하기 위해서는 이 파일을 Staged(기록) 상태로 만든 뒤, 커밋 하면 된다. 이를 반복하면 된다.

Naver Blog

Git 파일의 상태 확인하기

Git 파일의 상태 확인하기 이런 환경에서 실습을 해 보겠다. 파일의 상태를 확인하려면 보통 git status 명령을 사용한다. Clone 한 후에 바로 이 명령을 실행하면 다음과 같은 메시지를 볼 수 있다. 위의 내용은 파일을 하나도 수정하지 않았다는 것을 말해준다. 또한 현재 작업 중인 브랜치를 알려주며, 기본 브랜치 이름이 'master'이므로 현재 브랜치 이름이 'master'라고 나오는 것을 알 수 있다. 프로젝트에 README 파일을 만들어보자. 새로 만든 파일은 Untracked 상태가 될 것이다. Untracked files에 속한 파일들은 깃의 스냅샷에 저장되지 않은 파일들이다. 이를 커밋 하려면, 앞서 언급했듯이 Staged 상태로 변경한 뒤에 커밋 해야 한다.

Naver Blog

Git 파일을 새로 추적하기

파일을 새로 추적하기 git add 명령으로 파일을 새로 추적할 수 있다. Changes to be committed에 속한 파일들은 Staged 상태이다. 이 상태에서 커밋을 실행하면 git add를 실행한 시점의 파일이 커밋 되어 저장소 히스토리에 남는다.

Naver Blog

Git Modified 상태의 파일을 Stage 하기

Modified 상태의 파일을 Stage 하기 이미 깃에 커밋 되어 있던 파일을 수정하는 법을 알아보자. sample.txt 파일을 수정하고 나서 git status 명령을 다시 실행하면 결과는 아래와 같다. Changes not staged for commit에 속한 파일들은 Tracked 상태이지만, Staged 상태가 아니라는 뜻이다. 이 파일들을 커밋 해주려면 다시 git add 명령을 통해 Staged 상태로 만들어 주어야 한다. 즉, git add 명령은 새로운 파일을 추가할 때나, 수정한 파일을 추가할 때 모두 사용된다. 따라서 git add 명령은 '파일'을 추가하는 것이 아니라 다음 '커밋'에 추가한다고 생각하는 것이 좋다. 두 파일 모두 Staged 상태이므로 다음 커밋에 포함된다. 하지만 여기서 sample.txt 파일을 더 수정한다면 어떻게 될까? sample.txt 파일이 Staged면서 동시에 Unstaged라고 나온다. 어떻게 이런 일이 가능할까? 지금 이

Naver Blog

C 언어의 랜덤 넘버, 과연 균일할까?

C 언어의 랜덤 넘버(rand), 과연 균일할까? 지금까지 내 블로그에 한 목록에는 한 책의 내용이나, 한 프로젝트 단위로 묶어서 작성했었는데 막상 가끔가다 하나씩 배우는 것들에 대해서는 마땅히 정리한 것이 없는 것 같아 이 목록에 정리해 보려고 한다. 가장 먼저 다루어 볼 내용은 c언어의 rand 함수이다. rand() rand 함수는 다들 알고 있겠지만, 의사 난수를 생성해주는 함수이다. srand를 사용하여 시드를 선택할 수 있으며, srand를 사용하지 않으면 1번 시드를 사용한다. 하지만 이런 다들 아는 얘기를 하려는 건 아니고.. rand 함수는 215개의 int형 숫자 중 하나를 반환한다. 즉, 0~32767까지의 정수를 돌려준다고 생각하면 된다. 이 중 각각의 숫자가 나올 확률은 1/32768로 동일할 것이다. 그런데, 우리는 보통 1~10까지의 숫자를 얻고 싶을 때, (rand() % 10) + 1 과 같은 방법을 사용한다. 이 경우 1~10의 분포가 과연 동일할까?

Naver Blog

C 언어, 배열의 크기를 변수로 선언할 수 있을까?

C 언어, 배열의 크기를 변수로 선언할 수 있을까? 우리는 흔히 C 언어에서 배열의 크기를 선언할 때, 상수만 사용할 수 있고 변수는 사용할 수 없다고 배우고, 또한 그렇게 알고 있는 경우가 많다. 하지만 정말 그럴까? Visual Studio의 경우 상수로 계산되지 않았습니다. 변수로 인해 오류가 발생했습니다. 와같은 오류가 발생한다. 대부분의 C 언어 사용자가 사용하고 있을 마이크로소프트사의 Visual Studio에서는 위의 사진과 같은 오류가 발생한다. 아마 이 글을 읽는 대부분의 사람들이 보아왔을 것이다. 하지만 다른 컴파일러에서는 어떨까? GCC(GNU C Compiler)의 경우 배열이 변수 크기로 할당된다?? 어떻게 이런 일이 가능할까? 사실 배열의 크기를 변수로 선언할 수 있는 것은 표준(C99)에서 보장한다! 그렇게 때문에 GNU 등의 컴파일러에서는 당연히 지원하고 있으며, 마이크로소프트사의 Visual Studio에서 표준을 지키지 않고 있는 것이다. 사실 같은

Naver Blog

C 언어에서 쓰레드 할당은 어떻게 할 수 있을까?

C/C++에서 쓰레드 할당/사용하기 최근 코딩 테스트를 보다가 쓰레드를 사용하는 문제가 나온 적이 있다. 어느 기업의 코딩 테스트인지는 밝히지 않겠지만, 그전까지 C++에서 쓰레드를 사용해본 적이 없었는데 처음 사용해보고 재미있다고 생각하여 기록해둔다. 먼저 다음 소스 코드를 살펴보자. #include <stdio.h> void printString(char *arr) { for (int i = 0; arr[i] != '\0'; i++) printf("%c", arr[i]); printf("\n"); } void printNumber(int *arr) { for (int i = 0; i < 10; i++) printf("%d", arr[i]); printf("\n"); } int main() { char String[20] = "Hello World!"; int Number[10]; for (int i = 0; i < 10; i++) Number[i] = i; printString(

Naver Blog

C++ STL, iterator 없이 사용할 수 있을까?

C++ 11 auto (stl 사용 시 타이핑 줄이기) c++ stl을 사용하다 보면 iterator를 사용하게 되고, iterator를 사용하게 되면 필연적으로 코드가 길어지고, 타이핑을 많이 하게 되면서 짜증 내던 상황을 많이 겪었다. c++와 stl을 자주 사용하는 사람들이라면 이런 경험이 많을 것이다. 오늘은 이런 불편함을 줄일 수 있는 auto에 대하여 알아보고자 한다. C++ stl set의 경우.. stl에서도 사실 stack, queue 등은 별도의 인덱스가 필요 없고, vector는 배열과 같은 정수 인덱스로 접근이 가능하니, 보통 iterator를 많이 사용하는 경우는 set, map을 사용하는 경우이다. 이 글에서는 set을 예로 들어 설명해보겠다. set은 균형 이진 탐색 트리를 구현해놓은 컨테이너이다(참고 : C++ Standard Library 튜토리얼·레퍼런스). stl을 처음 알았던 날, 아래와 같이 사용하려고 했던 건 기억이 난다. 배열과 같은 인덱스

Naver Blog

배열을 초기화하는 방법에는 어떤 방법들이 있을까?

for 반복문을 사용하지 않고 int 배열을 0으로 초기화, -1로 초기화, 임의 정수로 초기화, 연속된 정수로 초기화하는 방법. int 배열을 사용하는 경우에는 처음에 배열을 어떤 값으로 초기화하는지가 상당히 중요한 경우가 많다. 사실 for 반복문을 사용한다면 간단한 일이지만 코드 길이를 조금이라도 줄여보겠다고 반복문을 사용하지 않고 함수 하나로 초기화할 수 있는 방법을 찾는 경험을 하는 경우가 많고, 이 글을 읽는 여러분들 또한 그런 생각에서 이 글을 읽게 된 것이라고 생각한다. 배열의 초기 값들은 쓰레기 값들로 가득 차있다. 1. memset 첫 번째로 알아볼 함수는 많이 사용하는 memset이다. memset은 c 언어의 <string.h> 헤더 파일에 존재하며, 연속된 메모리의 값들을 한 번에 지정해줄 때 사용된다. 하지만, int 타입 배열에 사용하기에는 적절하지 않다는 단점이 존재한다. 0, -1만 제대로 적용이 되고, 1을 넣으니 배열에 다른 값이 저장되는 것을 볼

Naver Blog

퀵 정렬(Quick Sort)과 최악의 경우(O(N^2))를 방지하기 위한 방법들

이 글에서는 퀵 정렬에 대한 상세한 설명은 하지 않는다. 퀵 정렬은 평균 O(NlogN)의 시간 복잡도를 가지지만, 최악의 경우 O(N^2)의 복잡도를 갖는다. 그 이유를 모르는 사람에게는 이 글을 추천하지 않으며, 이 글을 읽을 시간에 자료구조 책을 보기를 권하겠다. 이 글에서는 내가 여러 알고리즘 서적들과, 블로그 등을 보면서 만나본 여러 가지 최악의 경우 방지 방법을 다루어보고, 이를 비교해보고자 한다. 1. Quick Sort 첫 번째로, 그럼 퀵 정렬의 평균적인 경우와 최악의 경우의 시간 차이가 얼마나 발생하게 되는지를 먼저 알아보자. 다음 소스코드는 pivot을 배열의 첫 번째 원소로 하는 단순한 퀵 정렬의 소스코드이다. void firstPivotQicksort(int *arr, int begin, int end) { if (end <= begin) return; int pivot = begin, left = begin, right = end + 1; while (lef

Naver Blog

C++에서 nullptr을 사용해야 하는 이유

C, C++에서 NULL은 포인터 값을 초기화하기 위한 상수로 주로 사용된다. C++ 11에 추가된 nullptr과 NULL은 어떻게 다를까? 왜 nullptr을 사용하는 것이 더 좋다고 하는 것일까? 그 이유를 알아보자. 1. int* 포인터에 정수 값 대입 다음 소스코드를 살펴보면 print 함수는 int 값을 인자로 받아 이를 전역변수 Integer에 대입하고 그 값을 출력한다. int Integer, *Pointer; void print(int ptr) { Integer = ptr; cout << "integer : " << ptr << endl; } int main() { Pointer = &Integer; print(10); } 2. NULL은 포인터인가? 우리는 다음과 같이 포인터에 NULL을 대입하는 방식을 많이 사용한다. 그렇다면 NULL은 포인터인가? 다음 소스코드를 보자. int Integer, *Pointer; void print(int ptr) { Intege

Naver Blog

C/C++의 디버깅 함수 assert()란?

1. assert 함수란 어떤 함수인가? C/C++에서는 프로그램에서 오류가 발생할 경우 프로그래머가 해당 오류의 원인을 찾을 수 있도록 지원하는데, 이때 사용되는 함수가 바로 assert 함수이다. assert 함수는 C언어에서는 'assert.h' 헤더 파일에, C++ 언어에서는 'cassert' 헤더 파일 내에 선언되어있다. 이 글에서는 assert 함수를 사용하면 좋은 점과 사용하는 방법, 그리고 매크로를 사용하여 assert 함수와 비슷한 기능을 구현해 보는 법을 다루어보겠다. 2. assert 함수를 사용하지 않는다면.. 다음 소스코드를 살펴보자. devide 함수는 두 int 값들을 인자로 받아서 나눗셈 한 결과를 double형으로 돌려주는 함수이다. #include <iostream> #include <cassert> using namespace std; double divide(int _dividend, int _divisor) { return (double)_div

Naver Blog

C++ 11 Range-Based For Loop란?

C++ 11에 추가된 Range-Based For Loop란 무엇일까? Range-Based For Loop란 어떤 컨테이너의 크기만큼 for 반복문을 사용할 때, 기존의 for 반복문과 같이 for(int i=0; i<N; o++)와 같이 사용하는 것이 아니라, 컴퓨터가 자동으로 컨테이너의 크기를 계산하여 원소 하나하나씩 순서대로 반복문을 처리해 주는 것을 말한다. 기존의 For 반복문은.. 우리는 흔히 배열의 크기만큼 for 반복문을 사용할 때 다음과 같이 사용한다. 배열의 크기를 미리 알고 있다면 printArrToMaxsize() 함수와 같이 배열의 크기만큼 반복을 할 것이고, 배열의 크기를 모른다면 printArrToSizeofArr() 함수와 같이 sizeof(Arr)과 같은 방법을 사용할 수도 있다. #include <iostream> using namespace std; const int MAXN = 10; int Arr[MAXN]; void printArrToMaxs

Naver Blog

[LG CNS IT 콘서트] &quot;클라우드, 기업 경영의 새로운 길을 열다&quot; 후기

[LG CNS IT 콘서트] "클라우드, 기업 경영의 새로운 길을 열다" 후기 4월 24일 수요일. LG CNS에서 주최한 블로그 독자 초청 클라우드 세미나를 다녀왔다. 신청은 LG CNS 블로그에서 했었고(한참 전에 마감되었다), 나는 신청 기간 초반에 신청을 했었던 것 같다. 신청 결과는 나중에 문자로 통보가 되었고, 문자에 세미나를 들으면서 먹을 수 있는 저녁식사를 제공한다고 하길래 '샌드위치겠구나'라고 생각했던 것 같다..ㅎㅎ 이 외에도 주스와 커피도 있었다 ㅎㅎ 결과부터 말하자면, 너무 만족스러웠다. 회사는 크고 깨끗하고, 샌드위치는 맛있고, 강의는 너무 유익했다. 나는 사실 그동안 클라우드에 대해서 공부해본 적은 없었는데, '개발자라면 이런 정도는 공부해줘야겠지'라고 막연히 생각하고 신청했었다. 그래서 어려운 내용일 많을까 봐 걱정을 많이 하기도 했는데, 강연자분께서(어떤 팀장님이라고 하셨는데 죄송하게도 팀명이나 성함은 기억이 나지 않는다..) 너무 쉽게 잘 강연을 해주셔

Naver Blog

[우아한 Tech 세미나] &quot;의식적인 TDD, 리팩토링 연습을 통한 클린 코드 문화 만들기&quot; 후기

우아한 Tech 세미나 4/25일 목요일에 우아한 태크 코스에서 진행한 우아한 Tech 세미나에 다녀왔다. 잠실까지 다녀오는 길이 힘들었지만, 꽤 괜찮았던 경험이었다. TDD, 리팩토링, 클린 코드 개인적으로 최근에 읽은 책 중 가장 인상 깊은 책을 꼽으라면 로버트 마틴의 "클린 코드"를 꼽고 싶다. 이 책을 읽게 된 계기를 간단히 말해보자면 PS 위주로 알고리즘을 공부하는 많은 사람들이 그렇겠지만, 나 또한 코드를 지저분하게 짜는 편이었다. 하지만 우연한 계기로 코드를 정말 예쁘게 짜는 분과 함께 Pair Programming을 해볼 기회가 생겼었는데 이때 정말 많은 충격을 받았다.(여기서 말하는 예쁘게 짠다는 말은 처음 보는 코드임에도 주석이 필요 없을 정도의 가독성을 가진 코드를 말한다) 이런 경험을 통해 클린 코드라는 책에 관심을 가지게 되고 읽어보게 되었는데, 사실 이 책의 내용 대부분은 주옥같은 글들이지만, 클린 코드뿐만 아니라 내가 잘 알지 못했던 TDD, 리팩토링 등에

Naver Blog

[GDG Campus Korea] &quot;러닝머신 말고 머신러닝&quot; 후기

Hello to ML & AI 4/27 토요일, GDG Campus Korea에서 주최한 "러닝머신 말고 머신러닝: hello to ML & AI" 세미나에 다녀왔다. 사실 나는 인공지능은 공부해본 적이 없는데 지난번 LG CNS 클라우드 세미나에 다녀왔을 때와 마찬가지로 '내가 인공지능을 전문적으로 하지 않더라도 어느 정도는 알고 있어야 하지 않을까?'라는 생각에 다녀왔다. 나름 배운 것도 많고, 생각해볼 거리도 많았기 때문에 만족스러웠다. 생각해볼 만한 화두.. ※ AutoML은 궁극적으로 비전문가들이 ML을 쉽게 사용할 수 있도록 하는 것을 목표로 하고 있다. 하지만 비전문가들이 워드, 엑셀, 포토샵 등의 툴을 다루듯이 ML을 다룰 수 있게 된다면, ML 엔지니어들은 과연 어떤 일을 해야 할까? 어떤 일을 할 수 있을까? ※ ML 엔지니어에게는 AutoML이 어떤 도움을 줄 수 있을까? ※ 인공지능에게 학습 시킬 데이터를 수집할 때, 어떤 방법들을 사용할 수 있을까? 발로 직접

Naver Blog

C언어의 문자. character

C언어의 문자(chrarter) C언어에서는 알파벳 a~z, A~Z 혹은 숫자 0~9 등의 '문자'가 존재한다. 하지만 실제로 컴퓨터는 모든 데이터를 숫자로 저장하고 있기 때문에, 컴퓨터의 메모리에는 숫자만이 저장되어 있다. 즉, 컴퓨터의 메모리는 숫자를 저장하고 있지만 특정 숫자를 특정 문자로 표현하기로 사전에 약속해 놓음으로 우리는 컴퓨터로 문자를 표현할 수 있는 것이다. 이 약속 중 대표적인 것이 바로 그 유명한 아스키(ASCII) 코드이다. 이 글에서는 C언어에서의 '문자'에 대하여 아주 기초적인 내용을 다루어보려고 한다. C언어의 알파벳 C언어에서 숫자 65는 a를, 숫자 97은 b를 나타낸다는 사실은 C언어를 처음 배울 때 알게 되는 사실이다. 이 글에서는 이 '문자'들이 숫자로 이루어져 있기 때문에 가능한 연산들에 대하여 다루어 보겠다. a와 A는 숫자로 32만큼 차이가 난다. 즉, 65 + 32 = 97인데, 이를 코드로 옮겨보면 다음과 같다. 즉 문자 A에 숫자 32

Naver Blog

안녕하세요 로졔입니다.

3년만에 돌아왔습니다. 사실 이 블로그는 제가 컴퓨터공학과에 재학중인 대학생이던 시절. 취업에 도움이 될까 싶은 생각에 만든 블로그였습니다. 그때 당시 제가 관심있었던 분야는 IoT와 AI(머신러닝에 대한 공부보다는 API의 활용 방면에서) 였고, 제가 관심있는 분야를 혼자 공부하다보니 공부를 하고 블로그를 통해 다른분들에게 제 경험을 공유해드리는 것도 항상 즐거운 마음으로 할 수 있었습니다. 하지만 2019년 7월 우연한 계기로 그동안 제가 공부해오던 것과는 거리가 먼 금융권 IT개발자로 취업을 하게 되면서, 회사에서 다루는 스펙은 제가 원하는 방향과 점점 멀어지고 스스로도 공부에 대한 의욕을 잃으면서 블로그 활동을 중단한지 3년이라는 시간이 흘렀습니다. 그러나 최근들어 3년동안 회사에서 신기술을 다루지 않더라도 내가 배운게 없는게 아닌데.. 하는 생각이 많이 들더군요.. 제가 그동안 회사를 다니며 배웠던 것, 경험했던 것들을 기록하고 이런 정보들을 필요로 하는 사람들도 있을 것이

Naver Blog

[AIX/Linux] OS 버전 확인

AIX와 Linux 서버의 OS 및 버전 확인 방법 차이 # AIX 명령어 oslevel -s 결과 6100-07-10-1415 AIX에서는 위와같은 oslevel 명령어를 통해 AIX 버전을 확인할 수 있다. "6100..."이면 "AIX 6.1" 버전이라는 뜻. # Linux 명령어 cat /etc/os-release 결과 NAME="Red Hat Enterprise Linux Server" VERSION="7.3" 대부분의 리눅스 서버들은 OS에 대한 정보가 /etc/os-release 파일에 기록되어있다. 해당 파일을 읽으면 OS 종류 및 버전까지 알 수 있음.

Naver Blog

[AIX/Linux] 디렉토리 용량 확인(du)

내가 관리하는 서버는 한 서버내에 19개의 시스템이 돌아가고있다.. 이렇다보니 디렉토리 용량이 70%~80%를 자주 넘어가 디렉토리 용량에 민감한 편인데, 용량확인을 할 때 사용하는 명령어를 정리해 둔다. * 내가 관리하는 서버는 AIX 서버도 있고, Linux 서버도 있는데 du 명령어는 AIX와 Linux에서 옵션이 완전히 다르기 때문에 본인의 운영체제에 따라 잘 알아두는게 좋다. 나의 경우는 양쪽 서버를 모두 관리하는 만큼 주로 양쪽에 모두 적용되는 옵션만을 위주로 사용하는 편이다. /app/hom/ /app/mob/ /app/loan/ /app/chatbot/ /app/admin/ 먼저 위와 같이 시스템별로 디렉토리가 있다고 하자. 만약 여기서 du 명령을 그냥 친다면 해당 디렉토리 뿐만 아니라 모든 하위 디렉토리들의 용량을 보여준다. @ /app/hom/에서 du 8 ./d1 40 ./d2/dd1 408 ./d2/dd2 86248 ./d2 86280 . /app/hom/에서

Naver Blog

[AIX/Linux] 서버 내 파일 자동삭제(crontab)

내가 회사에서 담당하게 된 웹서비스에서는 고객이 이미지파일을 서버에 업로드하는 기능이 있었다. 서버에서는 업로드 된 이미지 파일을 전자문서 시스템에 저장한뒤 파일을 삭제했는데 이때 파일을 삭제하기위해 고려된 방법은 아래 3가지가 있었다. 서버 소스코드에서 이미지파일을 전자문서 시스템에 저장 성공할 때마다 이미지 파일 삭제 서버 소스코드에서 1일 단위로 배치를 돌면서 이미지파일을 삭제한다. 소스코드에서 파일 건드리기 싫다. 리눅스 rm 명령을 배치로 돌릴 수 있는지 찾아보자. 이 글의 제목만 봐도 모두 예상했겠지만, 내가 선택한 방법은 3번이었다. 일단 1번은 가장 먼저 제외했는데, 고객이 이미지를 업로드하는 화면이 계속 생길 예정이며 이걸 여러 개발자가 작업하다보면 파일 삭제로직이 누락될 수도 있을 것이라고 봤기 때문이다(이런 일은 일어나면 안되지만 종종 발생한 경험이 있었다) 따라서 서로 다른 화면이어도 이미지 파일이 올라가는 경로를 하나로 두고 일배치로 파일들을 삭제한다면 위와

Naver Blog

[Spring MVC] 환경세팅 1. java 8 설치

설치 과정 java 8 설치 이클립스(eclipse) 설치 Spring 설치 tomcat 설치 프로젝트 실행 H2 DataBase 설치 먼저 자바부터 설치해 주자. java 8을 설치해 주겠다. 오라클 홈페이지(https://www.oracle.com/)에서 다운로드할 수 있다. https://www.oracle.com/에서 Products 메뉴 선택 Products 메뉴에서 Java 선택 Java 화면에서 Java SE Download Java now 선택 Java 8이 있다. Java 8에 보면 Windows 탭과 x64.exe 파일을 다운로드할 수 있다. jdk-8u333-windows-x64.exe 파일을 다운로드해 주자. 참고로 다운로드하려면 오라클 회원가입을 해야 한다. 다운로드했다면 그냥 설치해 주면 된다. 설치가 완료되면 cmd에서 java -version 설치가 완료되면 cmd 창에서 java -version 명령어를 입력해 보자. Java version "1.8.0

Naver Blog

[Spring MVC] 환경세팅 2. 이클립스(eclipse) 설치

설치 과정 java 8 설치 이클립스(eclipse) 설치 Spring 설치 tomcat 설치 프로젝트 실행 H2 DataBase 설치 Java 8을 먼저 설치했다면, 이제 이클립스를 설치해 주자. 이클립스는 2020-09 버전부터 java 11버전을 필수로 설치해 주어야 한다. 따라서 여기에서는 그 바로 앞 버전인 이클립스 2020-06 버전을 설치하도록 하겠다. 이클립스 홈페이지(https://www.eclipse.org/)에서 다운로드할 수 있다. https://www.eclipse.org/에서 Download 버튼 클릭 2022-06 버전을 다운 받을게 아니므로 Download 화면에서 Download Packages 클릭 우측 MORE DOWNLOADS에서 Older Versions 클릭 2020-06 클릭 R Packages 클릭 Windows x86_64를 클릭해서 다운로드할 수 있다. 이클립스는 .zip 파일로 다운로드하게 되는데 그냥 사용할 디렉터리에 압축 해제 후

Naver Blog

[Spring MVC] 환경세팅 3. Spring 설치

설치 과정 java 8 설치 이클립스(eclipse) 설치 Spring 설치 tomcat 설치 프로젝트 실행 H2 DataBase 설치 Java 8, Eclipse를 설치했다면 이제 Spring까지 설치해 주자. Eclipse Marketplace에서 설치할 수 있다. 이클립스>Help>Eclipse Marketplace 클릭 검색할 필요도 없다. Popular 들어가면 있음. 그냥 Confirm 눌러주자 라이선스 동의 후 Finish 클릭 설치 중.. 설치가 완료되면 이클립스를 재부팅하라는 메시지가 뜬다. 재부팅해 주면 설치 완료.

Naver Blog

[Spring MVC] 환경세팅 4. tomcat 설치

설치 과정 java 8 설치 이클립스(eclipse) 설치 Spring 설치 tomcat 설치 프로젝트 실행 H2 DataBase 설치 이제 서버를 설치해 주자. 서버로는 Tomcat 8을 사용할 예정이다. 아파치 톰캣 홈페이지(https://tomcat.apache.org/download-80.cgi)에서 다운로드할 수 있다. Tomcat 8에서 windows 64bit 용 다운로드 eclipse 폴더 안에 압축을 풀어주었다. elipse 폴더 안에 압축을 풀어주었다.

Naver Blog

[Spring MVC] 환경세팅 5. 프로젝트 실행

설치 과정 java 8 설치 이클립스(eclipse) 설치 Spring 설치 tomcat 설치 프로젝트 실행 H2 DataBase 설치 이제 설치해야 할 프로그램들은 모두 설치했으니 프로젝트를 생성/실행해 보자. 이클립스>File>New>Other 클릭 soring으로 검색 후 Spring Legacy Project 선택 Project Name을 입력 후 Spring MVC Project 선택, Next 클릭 프로젝트가 생성되었다. 이제 앞에서 설치한 Tomcat으로 서버를 띄워보자. Server에서 new server 클릭 설치했던 tomcat 버전(tomcat 8.5)을 선택해 주자 Browse 버튼을 클릭해 설치한 tomcat 경로를 지정해 준다. jre도 선택해 주자. Broese 버튼을 클릭해 설치한 tomcat의 경로를 지정해 준 뒤, 설치한 jre도 선택해 주자. 생성한 프로젝트를 Add 해주자. 이제 server에 Tomcat에 추가되었다. 우 클릭 후 Start 버튼

Naver Blog

[Spring MVC] Tomcat 서버 설정

Tomcat 서버를 세팅한 뒤, 더블클릭하면 서버 설정을 변경할 수 있다. 난 로컬 서버의 설정을 여기저기 변경했던 경우가 많은데 이 경험에 비추어 한번 설정들에 대해 이야기해 보려고 한다. Server name 을 변경할 수 있다. 2. Sever properties를 변경할 수 있다. common을 보면 Default가 UTF-8 이 아닐 수 있다. UTF-8이 아니라면 UTF-8로 변경해 주자. 3. 서버에 publish 되는 파일 경로를 변경할 수 있다. (default: workspace\.metadata\.plugins\org.eclipse.wst.server.core) - 기본적으로는 workspace 하위 경로로 설정되어 있지만, tomcat 폴더 밑이나 전혀 다른 폴더로 경로를 변경할 수 있다. 4. 소스코드를 수정했을 때 서버에 자동 배포(publish) 여부를 선택할 수 있다. - Never publish automatically : 자동 배포하지 않음 - Aut

Naver Blog

[Spring MVC] 스프링 버전 업데이트

처음 Spring MVC 프로젝트를 설치하게 되면, 스프링 3.1.1.RELEASE 버전이 설치되어 있다. 이 버전에는 존재하지 않는 어노테이션 등이 워낙 많기 때문에 최신 버전으로 업데이트해주자. 실제로 프로젝트의 .jar 라이브러리들을 보면 스프링 3.1.1.RELEASE 버전이 설치되어 있는 것을 알 수 있다. pom.xml 파일을 보자. <org.springframework-version>3.1.1.RELEASE</org.springframework-version> 위와 같이 org.springframework-version이 3.1.1.RELEASE라고 작성되어 있다. 스프링의 최신 버전을 확인하고 최신 버전으로 업데이트해주자. Maven Repository(https://mvnrepository.com/artifact/org.springframework/spring-context)에서 spring-context의 최신 버전을 확인할 수 있다. 최신 버전이 5.2.22.RE

Naver Blog

[Spring MVC] @GetMapping, @PostMapping, @RequestMapping

스프링 어노테이션 중 Controller 단에서 가장 많이 사용하게 되는 @GetMapping, @PostMapping, @RequestMapping에 대해 알아보자. @GetMapping @GetMapping(value = "/GetMapping") public String GetMapping(Model model) { return "home"; } @GetMapping을 선언한 뒤 GET, POST 방식으로 데이터를 요청해 보자. 포스트맨 등의 툴이 없어도 자바스크립트만으로도 GET, POST 요청을 날릴 수 있다. 내가 실무에서 테스트할 때 많이 사용하는 방법이다. 위 결과를 보면 먼저 날린 GET 요청에는 200 응답이 온 반면, 뒤에 날린 POST 요청에는 405 에러코드가 리턴된 것을 알 수 있다. 또한 요청 결과의 Response Headers를 보면 Allow : GET이라고 적혀있는 것을 볼 수 있다. @PostMapping @PostMapping(value = "/

Naver Blog

[JavaScript] Postman 등의 툴 없이 크롬 개발자 도구에서 Post 요청 보내기

이번에는 내가 회사에서 테스트를 할 때 많이 사용하는 방법으로 Postman 등 별다른 툴 없이 크롬 개발자 도구에서 Post 요청을 보내는 법에 대해서 작성해 보겠다. @RequestMapping(value = "/NameApi") @ResponseBody public Name NameApi(@RequestParam("Kname") String Kname, @RequestParam("Ename") String Ename, Model model) { Name name = new Name(); name.setKname(Kname); name.setEname(Ename); return name; } 먼저 Controller에 위와 같은 API가 선언되어 있다고 하자, 영문명과 한글명을 입력받아 json 형식으로 그대로 리턴해주는 코드이다. 실제로 Get 방식으로 요청을 해보면 json 리턴을 받는 것을 볼 수 있다. 이제 POST 요청을 해보자. var xhr = new XMLHttpR

Naver Blog

[Spring MVC] @RequestParam

@RequestParam은 Controller에서 request 요청의 파라미터를 java 변수에 바로 매핑해 줄 수 있는 어노테이션이다. @RequestMapping(value = "/RequestParam") public String RequestParam(@RequestParam("name") String name, Model model) { model.addAttribute("name", name); return "home"; } Controller에 위와 같은 코드가 있다고 하자. @RequestParam("name") String name 부분을 보면 request 요청의 name 파라미터를 String name 변수에 할당하겠다는 뜻이다. 위와 같이 선언하는 경우 RequestParam 메서드에서 name 변수를 바로 사용할 수 있다. 위의 코드에서는 model에 추가해 jsp로 바로 내렸다. 위와 같이 GET 요청의 파라미터로 보낸 name : Loze가 String

Naver Blog

[Spring MVC] @ResponseBody

@ResponseBody는 Controller에서 뷰(jsp)가 아닌 다른 값(ex, json 형식의 데이터 등)을 리턴해 주고 싶을 때 사용할 수 있는 어노테이션이다. @RequestMapping(value = "/home") public String home(@RequestParam("name") String name, Model model) { return "home"; } Controller에 위와 같은 코드가 있다고 하자. 위 경로로 요청이 온다면 Controller는 "home"을 보고 home.jsp 파일을 찾아서 보여줄 것이다. 뷰(jsp) 파일이 아니라 데이터를 그대로 리턴해줄 수 있을까? 이때는 Controller에 @ResponseBody를 추가해 주면 된다. @RequestMapping(value = "/home") @ResponseBody public String home(@RequestParam("name") String name, Model model) {

Naver Blog

[Spring MVC] jackson(Controller에서 json 형식으로 class 리턴해주기)

이 글은 Spring Boot에서는 기본적으로 지원하는 기능으로 Boot를 사용하고 계신다면 읽지 않으셔도 무방합니다. 혹은 Boot가 아니라면 이런 기능을 따로 추가해야 하는구나 하고 알고 넘어가셔도 좋습니다 인터넷 여기저기서 스프링 API 관련 글들을 보다 보면 아래와 같은 코드들을 볼 수 있다. @RequestMapping(value = "/NameApi") @ResponseBody public Name NameApi(@RequestParam("Kname") String Kname, @RequestParam("Ename") String Ename, Model model) { Name name = new Name(); name.setKname(Kname); name.setEname(Ename); return name; } static class Name { private String Ename; private String Kname; public void setEname(Stri

Naver Blog

[Spring MVC] 환경세팅 6. H2 DataBase 설치

설치 과정 java 8 설치 이클립스(eclipse) 설치 Spring 설치 tomcat 설치 프로젝트 실행 H2 DataBase 설치 웹서비스에는 DB가 빠질 수 없다. 어떤 DB를 사용해 볼까.. 고민을 하다 NoSQL도 좋지만 일단 회사에서 사용하는 RDBMS를 설치하기로 마음먹었다. 어떤 걸 사용해 볼까 고민하다가 사용해 본 적이 없기도 했고, 설치가 가장 간편하다는 H2를 사용해 보기로 했다. H2 공식 홈페이지(http://www.h2database.com/html/download.html)에서 다운로드할 수 있다. Windows 운영체제를 사용하고 있어도 굳이 설치 파일을 받아야만 하는 건 아니다. .zip 압축파일을 받은 후 압축 해제해서 사용해도 된다. 압축파일을 해제했다면 h2/bin/h2w.bat 파일을 실행해 주자. 위와 같은 화면이 열릴 텐데 여기서 알아둘만한 것은 설정의 Generic H2 (Embedded)와 Generic H2 (Server) 정도만 알아

Naver Blog

[Spring MVC] H2 DataBase - Spring 연결

지난 포스팅에서 H2 DataBase 설치하는 법을 알아보았고 이번에는 Spring에서 DB에 연결하는 법을 알아보자. #pom.xml 먼저 아래 4개의 라이브러리들(h2, mybatis, mybatis-spring, commons-dbcp)을 다운로드해 주자. <!-- H2 --> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>2.1.214</version> </dependency> <!-- mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.10</version> </dependency> <!-- mybatis-spring --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spr

Naver Blog

[Spring MVC] JUnit(서버를 띄우지 않고 테스트하기)

Spring에서 새로운 서비스나 쿼리 등을 개발했을 때 매번 이를 테스트하기 위한 Controller나 view를 만드는 것은 번거로운 일이다. JUnit이라는 라이브러리를 사용하면 그런 건 개발할 필요도 없을뿐더러, 로컬 서버를 띄우지도 않고도 테스트가 가능하다. #pom.xml JUnit을 사용하기 위해서는 JUnit과 spring-test 라이브러리가 필요하다. <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.7</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.2.22.RELEASE</version> </dependency> #테스트 이제 테스트하는 법을 알아보자. 일단 나는 이

Naver Blog

[여의도/점심] 서평옥

여의도 오투타워 지하 1층 서평옥 Previous image Next image 곰탕 9,500원 밑반찬으로 젓갈이 나온다. 곰탕은 밥이 말아져 나오고, 고기 양이 다른 집들보다는 조금 넉넉한 편. 시키면 바로 나오는 국밥이야말로 진정한 패스트푸드가 아닐까 싶다. 장점 : 국밥, 젓갈이 맛있다.

Naver Blog

[여의도/점심] 홍대돈부리

여의도 오투타워 지하 1층 홍대돈부리 에비동 11,000원 내가 개인적으로 혼대돈부리에서 가장 좋아하는 메뉴이다. 밥, 간장, 왕새우튀김의 환상의 조합. 장점 : 점심에 음식 나오는 속도가 빠르다. 새우 튀김이 맛있다.

Naver Blog

[여의도/점심] 동동국수

여의도 파이낸스빌딩 지하 1층 동동국수 육개장 칼국수 12,000원 육개장과 뒤에 있는 밥, 칼국수 면이 나온다. 밥과 면이 말아져 나오지 않고 따로 나오는데 그러다 보니 밥은 괜찮지만 면은 국물이 잘 배지 않는 것 같은 느낌도 있다. 또한 밥과 면의 양은 각각 공깃밥 절반 정도이다. 장정 : 육개장 시키자마자 바로 나옴. 육개장 양 많음. 단점 : 밥, 면 중 한쪽을 많이 먹고 싶다면 양이 부족할 수 있음.

Naver Blog

[여의도/점심] 오감면옥

여의도 IFC몰 지하 3층 오감면옥 물냉면 11,000원 들어가면 사진 뒤쪽에 보이는 작은 주전자에 육수를 담아주신다. 육수가 맛있어서 기대를 냉면을 너무 기대하게 된다. 냉면은 면도 맛있고 고명도 맛있지만 식초가 들어가서 나오는 게 단점(?) 냉면에 식초를 넣지 않는 입장에서는 안타까운 맛이다. 장점 : 맛있다. 특히 냉면에 식초를 꼭 넣어먹는 사람에게 추천 단점 : 냉면에 식초를 넣지 않는 사람들에게는 불쾌할 수 있다. 단 그래도 취향 차이일 뿐 맛은 있음.

Naver Blog

[여의도/점심] 현선이네 프리미엄(떡볶이)

여의도 IFC몰 지하 2층(여의도역-IFC몰 연결 지하통로) 현선이네 프리미엄 Previous image Next image 떡볶이 4,500원 꼬마김밥 4,000원 즉떡을 먹다 보면 다시 분식집 떡볶이가 땡긴다.. 떡볶이가 생각나면 항상 찾게 되는 곳. 매운맛은 안 매운맛, 중간 맛, 매운맛 3단계인데 안 매운맛은 말 그대로 매운맛이 아예 없다. 중간 맛부터가 살짝 매콤한 정도로 난 항상 중간 맛을 먹는다. 참고로 처음 간다면 위치를 찾기 어려울 수 있는데(주소가 ifc 지하 2층으로 되어있어서..) ifc 내부가 아니라 여의도역으로 연결된 지하통로에 있다 장점 : 떡볶이를 좋아한다면 누구나 맛있게 먹을 수 있다. 요즘 떡볶이들에 비하면 저렴하다(?)

Naver Blog

[여의도/점심] 팔당반점

여의도 BNK 금융 타워 지하 1층(진순대 맞은편) Previous image Next image 해물쟁반짜장 : 12,000원 육즙탕수육(소) : 20,000원 진순대 앞에 팔당반점이 생겼길래 방문해 봤다. 가게가 매우 넓고 회전율이 빠르기 때문에 웨이팅이 있더라도 금방 들어갈 수 있다. 해물쟁반짜장이 매우 특이한데, 사진과 같이 일반적인 짜장면 위에 빨간 양념이 따로 얹어져서 나온다. 하지만 맛은 정말 평범한 짜장면에 고춧가루 뿌려먹는 맛.. 반면 짜장면과 달리 탕수육은 너무 맛있었다. 장점 : 회전율 빠름. 탕수육이 정말 맛있다. 기본적으로 음식의 양이 상당히 많다(짜장면뿐 아니라 일행의 짬뽕, 가지 덮밥 모두 성인 남성도 배부를 만한 양이었다고 생각됨) 단점 : 짜장면은 아무리 점수를 좋게 줘도 무난한 맛. (탕수육을 먹기 위해 간 것이 아니라 짜장면을 먹으러 간 것이기 때문에) 재방문 의사 없음. * 2022.10.25 수정 기존 내용에는 일행의 가지 덮밥을 몇 입 먹어본

Naver Blog

[여의도/점심] 더미

여의도 현대차증권빌딩 지하 1층 더미 갈비탕 : 15,000원 요즘 같이 날씨가 추워지면 뜨끈한 국물이 땡긴다. 하지만 진순대 같이 줄 서는 곳은 가기 아까운 것이 직장인의 마음.. 그런 생각이 들 때마다 가는 곳이 더미이다. 내가 갈비탕에서 가장 중요하게 생각하는 점은 뼈에서 살이 얼마나 잘 발라지는가이다. 맛보다도 발라지는 걸 중요하게 여기는데, 더미는 내가 먹어본 갈비탕 중에서 살이 가장 잘 발라지는 집 중 하나이다. 가위는 들 필요도 없고 집게로 벼를 잡은 뒤 젓가락으로 살점을 잡아당기면 벼와 살이 싹 분리가 된다. 장점 : 가게가 넓어 자리가 많고 회전율이 좋아 웨이팅이 필요 없다. 갈비탕이 정말 맛있다. 단점 : 룸에 여러 테이블이 들어가는데, 옆자리에서 점심부터 고기를 굽고있으면.. 단언컨데 내가 먹어본 갈비탕 중 최고의 갈비탕이다.

Naver Blog

[Spring MVC] 유튜브(YouTube) 영상 삽입

웹 화면에 영상을 삽입하고 싶을 때, 영상을 먼저 유튜브(YouTube)에 업로드 해둔 뒤 해당 영상을 웹 화면에 삽입할 수 있다(링크 X). 예시 @Controller public class MediaController { private static final Logger logger = LoggerFactory.getLogger(MediaController.class); @GetMapping("/media/youtube") public String youtube(Model model) { return "youtube"; } } <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <html> <head> <title>유튜브</title> </head> <body>

Naver Blog

[여의도/점심] 이와타

여의도백화점(맨하탄빌딩) 지하 1층 이와타 Previous image Next image 파이탄소유(진한간장) : 13000원 카라아게 : 6000원 나는 라멘을 좋아하는데 어째서인지 여의도에는 라멘집이 많지 않은 것 같다. 어쩔 수 없이 줄 서야 하는 걸 알면서도 이와타에 간다. 가게는 작고 사람은 많아 항상 줄을 서야 한다. 그래도 줄 서는 시간이 아까운 집은 아니다. 라멘은 맑은 국물(ex, 소유)과 진한 국물(ex, 파이탄소유)이 있는데 난 개인적으로 맑은 국물은 너무 싱거운 느낌이라 진한 국물만 먹는다. 무겁고 맛있다. 계란도 맛있다. 카라아게는 양은 적지만 어차피 라멘으로도 충분히 배가 부르기 때문에 맛있게 한두 점만 먹는 느낌도 괜찮은 편이다. 하지만 가성비는 많이 떨어지는 편. 장점 : 무겁고 맛있다. 날이 추우면 더 생각나는 맛. 반숙 계란 맛있음.

Naver Blog

[여의도/저녁] 계림

맨하탄21리빙텔 2층 계림 닭볶음탕(중) : 39000원 닭볶음탕을 좋아한다면 한 번은 가봐야 하는 집. 사실 여의도에는 아일랙스 지하에 있는 집(여의도점)이 워낙 유명해서 여러 번 방문했지만 항상 웨이팅이 있어 다른 집으로 발걸음을 돌렸던 기억이 많다. 그러던 와중 국회의사당 근처에서 일하는 친구에게 국회의사당점은 사람이 없다는 소식을 듣고 함께 방문하게 되었다. 여의도점과는 다르게 텅 빈 가게가 인상적이었지만 다행히 맛은 완전히 동일한 맛이었다. 국물은 진하고 마늘 향, 맛도 강하다. 라면 사리도 맛있고 닭도 맛있다. 소주도 잘 어울리고 소맥도 잘 어울린다. 장점 : 계림 닭볶음탕이야말로 완벽한 음식이 아닐까?

Naver Blog

[여의도/점심] 샐러드스탑

샐러드스탑 동여의도점(폴바셋 맞은편) Previous image Next image 오크랩라(랩) : 10000원 날씨가 좋아져 점심에 피크닉이 생각날 때, 점심에 간단히 먹고 자고 싶은데 샐러드는 먹기 싫을 때 가장 먼저 생각나는 곳이 바로 샐러드스탑이다. 여의도에 근무를 한다면 사무실에 피크닉 매트 하나는 있어야 하는 것이 인지상정. 날씨 좋으면 점심엔 여의도 공원으로, 저녁엔 한강으로 가는데 밖에서 식사할 땐 그릇이 많지 않고 간단하게 먹을 수 있는 음식이 필수이다. 샐러드스탑에선 항상 오크랩라를 먹는데, 사진을 자세히 보면 보이겠지만 당면에 소스 범벅이다. 무조건 맛있을 수밖에 없는 맛. 여의도공원, 특히 증권가 근처에 있는 직장인들이라면 슬러드스탑 랩과 피크닉 매트 하나씩 들고 여의도공원 한 번씩 가는 걸 추천한다. 빌딩 안에만 있으면 정신건강에 해로울 것. 장점 : 간단하게 먹기 좋다. 맛있다. 단점 : 점심에 배달 주문이 많기 때문에 의외로 조리시간이 길다.

Naver Blog

공덕역/대흥역 평양냉면 맛집 을밀대

을밀대 평양냉면 서울특별시 마포구 숭문길 24 나의 첫 평냉집이자 최애 평냉집 을밀대. 점심시간이 1시간 30분이라면 여의도에서 택시 타고 다녀올 수 있다. 사이드 메뉴인 녹두전에 냉면과 굉장히 잘 어울리기 때문에 항상 시켜 먹는 편. 평양냉면 국물은 심심한 편은 아니지만 너무 진하지도 않은 맛이다. 개인적으로 심심한 육수를 선호하지 않아 이 집을 좋아한다.(여의도의 유명한 정인면옥은 육수가 너무 밍밍해서 개인적으론 불호) 녹두전은 기름냄새가 많이 나고 그만큼 고소한 맛이다. 웨이팅하고 있으면 녹두전 냄새가 진동을 해서 시켜볼 수밖에 없다. 녹두전의 느끼함을 냉면 육수가 싹 잡아주기 때문에 둘의 조합이 아주 좋다. 매년 가격이 오르지만 매년 재방문할 의사가 있음.(이라고하지만 이미 N차 재방문 중..)

Naver Blog

영등포구청역 쭈꾸미 맛집 설쭈

설쭈 영등포구청점 서울특별시 영등포구 양산로17길 22 당산동 2차 어울림 쭈꾸미라면 환장하는 나에게 있어 동네에 존재하는 쭈꾸미 맛집. 점심에는 가본 적이 없고 종종 퇴근 후에 방문해서 먹거나 포장해서 집에서 먹는다. 저녁에는 사람이 거의 없다. 매운맛은 3단계가 존재하며 1단계도 신라면보단 훨씬 맵다. 다만 엽떡이나 마라탕 좋아한다면 1단계는 싱거울 것.(맵찔이는 2,3단계 먹어보지 않아서 얼마나 매운지 모름..) 재방문 의사 있는 수준이 아니라 이미 두자릿 수 방문.

Naver Blog

을지로입구역/종각역 우육탕 맛집 우육면관

우육면관 청계천점 서울특별시 종로구 청계천로 75-2 회사 교육이 있어 1년 만에 간 듯한 청계천과 종각. 귀찮아서 가까운 식당을 찾아보던 중 발견한 우육면관. 일반 우육면과 특우육면이 면 양은 동일하며 고기 양이 다르다길래 특으로 시켰다. 국물은 먼가 장 맛이 진한 느낌인데 뭔지는 잘 모르겠다. 고기는 양이 상당히 많아서 만족. 면은 양이 많지 않지만 밥을 공짜로 추가해 먹을 수 있다. 다만 국물과 밥이 어울리는지는 잘..(내 취향은 아니었음) 그래도 맛은 있었음. 그리고 사이드 메뉴로 수교가 있었는데 나름 괜찮았다. 다만 난 군만두 파라서 살짝 아쉽긴 했음. 이렇게 적으니 불만만 많은 것 같지만 사실 맛있게 먹었다. 다 먹고 나서 청계천 산책하는 것도 좋았음.

Naver Blog

명동역 에스프레소바 리사르커피

리사르커피 명동점 서울특별시 중구 명동8가길 58 1층 커피 좋아하는 사람, 에스프레소바 좋아하는 사람 중 리사르를 모르는 사람이 있을까? 사실 난 예전에 한번 명동점에 방문한 적은 있었다.(아마 을지로에 볼일이 있었는데 리사르 가보고 싶어서 명동까지 갔을 듯, 예전이라 기억은 잘 안 남) 그때 너무 맛있게 먹었던 기억이 있어서 청계천에서 명동까지 산책할 겸 걸어서 오랜만에 재방문을 했다. 평일 오후에 방문해서 그런지 사람이 없고 텅 비어있어서 살짝 놀랬지만 편하게 마시기 좋았다. 내가 제일 좋아하는 카페 로마노. 리사르에선 생레몬이 아니라 레몬청을 주는데 개인적으로 극호. 커피의 고소한 맛과 설탕의 단맛 그리고 레몬향의 조화가 너무 좋고 레몬 과육이 없기 때문에 시지 않다. 두 번째 잔은 시원한 카페 그라니따. 에스프레소 슬러시?라고 하는데 너무 차가워서 아쉽게도 내 취향은 아니었다. 더울 때 먹으면 맛있을 것 같지만 에어컨도 빵빵하고 가게가 워낙 시원했기 때문에 따뜻한 커피를 시

Naver Blog

을지로3가역 파스타/뇨끼/와인 맛집 시옷시옷음식작업소(ㅅㅅ음식작업소)

시옷시옷음식작업소 서울특별시 중구 수표로 30 OK빌딩 2층 몇 달 만에 을지로 간 김에 저녁엔 맛있는 걸 먹으려고 식당을 여러 군데 찾아보다가 그냥 네이버 예약이 되는 곳으로 예약했다.(예약금이 있기 때문인지 예약은 쉽고 널널했음) 처음부터 끝까지 양식집인데 예약할 때까지만 해도 퓨전 술집인 줄 알아서(다른 음식점과 헷갈린 듯) 당일 메뉴 보려고 찾아봤다가 황당했던 기억이 난다. 퇴근 후 식장에 방문하니 네이버 예약 시 결제한 예약금은 바로 환불해 주셨다. 둘이서 간만큼 일단 음식 2개를 시키고 글라스 와인과 보틀에서 5초 정도 고민하다가 레드와인 제일 싼 보틀로 한 병 시켰다. 음식은 라구 파스타와 시금치 뇨끼. 라구 파스타는 뻔한 아는 맛이지만 맛있을 수밖에 없는 그런 맛이다. 뇨끼는 시금치 맛은 전혀 안 나고(대충 맛있다는 뜻) 크림소스에 감자 맛이 많이 나는 맛이었다.(이것도 맛있다는 뜻) 둘 다 맛있게 먹었다. 둘 중 하나만 선택한다면 뇨끼가 더 맛있긴 했음. 와인은 칠레

1 2 3 4