2018년 5월 27일 일요일

veamcamp HTML+CSS 재미있게 입문하기 2주차

오늘 배운 내용은 선택자(selector)에 대한 내용. 그리고 하나의 페이지를 구성하는데 있어서의 접근법. 다른 UI framework를 다루더라도 유사하게 적용되는 개념이다.

디자인은 단순히 예쁜 화면을 의미하는 것이 아니라 의사 결정, 사고 방식을 포함하는 개념임을 잊지 말자.

레이아웃을 만드는데 앞서 우선 html을 구성하는 각 태그가 block element인지 inline element인지 알아야 한다. div, ul, li, h1~h6과 같은 태그는 block element에 속한다. 그리고 a, span, img 등의 태그는 inline element에 속한다. Block element는 box-model을 따르며 inline element는 그렇지 않으므로 둘을 올바르게 구분할 수 있어야 원하는 결과물을 얻을 수 있다.

img 가운데 정렬 (* inline element 가운데 정렬)

img 태그로 작성된 내용이 text-align: center;에 의해 가운데 정렬이 된다는 점에선 다소 불만스러운 부분이 있지만 어쨌든 inline element에 대한 가운데 정렬엔 text-align 스타일 속성이 쓰인다고 한다. 모든 태그 요소에 대해 하나의 방법으로 horizontal align과 vertical align 속성을 지정할 수 있다면 누구에게나 좋은 상황일텐데 표준화란게 참 어렵긴 어려운가 보다.

css 별도 파일로 구분하기

역할이 다른 내용은 서로 다른 파일로 관리하는 것이 바람직하다. 특히 인라인 스타일은 지양해야 한다. css 파일은 별도 파일로 분리하는 것이 관리 측면에서 좋다.
<link rel="stylesheet" href="style.css">

레이아웃

화면을 구성할 때엔 레이아웃을 먼저 생각해야 한다. 당연한 얘기지만 큰 단위에서 작은 단위로, 작은 단위에서 더 작은 단위로 구체화 시켜 나가야 한다. 개별 요소에 대한 style은 가장 나중의 일이다.

화면 요소의 단위를 나누는 데에도 일종의 룰, 컨벤션이 있다. header - contents - footer의 3분할 구성이 일반적으로, 가장 외곽의 div는 wrapper라든가 container라든가 하는 이름을 붙인다
<div class="wrapper">
  <div class="header"></div>
  <div class="contents"></div>
  <div class="footer"></div>
</div>

Reset css

h1, li 등의 태그엔 bold체로 지정된다든가 bullet이 붙는다든가 하는 등의 기본적으로 할당되는 스타일이 있다. 거슬린다면 스타일을 제거하고 원하는 형식으로 새롭게 지정해줄 수 있다. 크롬의 검사 기능이 유용하게 쓰이는데 크롬의 검사 기능을 이용하면 각 요소가 잡히는 사이즈를 확인할 수 있을 뿐만 아니라 기본으로 지정된 스타일이 무엇인지에 대해 알 수 있다. 

기본 스타일을 무효화 해보자.
h2, ul {
  margin: 0;
  padding: 0;
}

li {
  list-style-type: none;
}

선택자

자세한 내용은 w3schools.com reference를 참고하자. (https://www.w3schools.com/cssref/css_selectors.asp)

선택자, selector는 특정 요소에 스타일을 지정하거나 동작을 부여할 때 활용되는 개념이다. 상위-하위의 관계를 표현해 특정 요소를 한정할 수 있으며 별도로 부여한 class나 id 값을 기준으로 특정 요소를 지정할 수 있다. (class는 '.'으로, id는 '#'으로 참조한다.) 그리고 :hover 등의 가상 선택자를 통해 특정 액션에 대한 스타일을 지정해줄 수도 있다.
.section li:hover {
  border-left: 5px solid dodgerblue;
  color: dodgerblue;
}

.info {
  background-image: url(images/icon-info.png);
  background-repeat: no-repeat;
  background-position: right center;
}

끝.




2018년 5월 23일 수요일

Blocking, Non-Blocking, Synchronous, Asynchronous.

면접에서 non-blocking과 asynchronous의 차이점을 질문받았었는데 제대로 답변하지 못했다. Blocking와 non-blocking 차이점을 말씀드린 후, synchronous와 asynchronous의 차이점을 말씀드리는 편이 나았을 것 같다. 아니면 blocking과 non-blocking의 차이점을 설명해보라는 질문이었다면 좀 더 나은 상황(?)이었을 것이다.

다 알고있다고 생각했던 개념이었지만 막상 설명하려고 하면 말문이 막히는 개념.. 정리해보고자 한다. 아래 링크의 자료가 가장 큰 도움이 되었다.
https://www.slideshare.net/namhyeonuk90/tcp-ip-io-model


Blocking vs Non-Blocking

Blocking, non-blocking은 호출한 입장에서 구분지을 수 있다. 함수(system call)를 호출했을 때 처리 결과와 무관하게 바로 리턴 받아 제어권을 갖을 수 있으면 non-blocking. 일반적인 함수 호출에서처럼 작업이 끝날 때까지 대기해야 하면(작업이 끝날 때가지 리턴이 없음) blocking.


Synchronous vs Asynchronous

Synchronous, asynchronous는 함수의 처리방식에서 구분지을 수 있다. 작업 완료 여부를 누가 신경쓰냐에 대한 것으로 함수의 작업 완료 후 리턴을 기다리거나 바로 리턴을 받더라도 작업 완료 여부를 스스로 확인하면 synchronous. 작업을 요청해놓고 다른 일을 하다가 해당 작업이 완료되면 완료되었음을 통지 받고 그에 따른 처리를 하는 모델은 asynchronous. (통지 방식; 델리게이트, 퓨처, 프로미스, 콜백)

→ 결과 형태의 구분으로 non-blocking과 asynchronous를 구분하기도 하고, 의견은 다양하다.

! 추가로 I/O 모델과 I/O 이벤트 통지 모델에 대한 정리. 마찬가지로 위 슬라이드 쉐어 링크에 자세히 정리되어 있다.

I/O

I/O에서 대화의 주체는 커널과 프로세스다. I/O 작업은 사용자 레벨에서 할 수 없기 때문에 프로세스는 커널에게 I/O를 요청해야 한다. 그리고 커널은 프로세스에게 I/O 상황을 응답(통지) 한다.


Blocking I/O

Blocking 모델로 클라이언트 별로 스레드를 생성해서 처리하는 방식이 일반적이다. 클라이언트 수가 많아질 수록 많은 스레드의 생성을 요구하기 때문에 스레드 생성 비용, 스레드 간 스위칭 비용 등 성능상 비효율적이다.


Non-Blocking I/O

I/O 작업을 진행하는 동안 유저 프로세스의 작업을 중단하지 않는다. selector나 poll에 여러 소켓을 바인딩 시킨 후 하나의 채널(스레드)에서 관리한다.


I/O 이벤트 통지 모델

Non-Blocking I/O의 개선 버전. 마찬가지로 하나 또는 적은 스레드로 다수의 클라이언트를 제어할 수 있다. I/O 처리를 할 수 있는 소켓(또는 fd)를 가려내서 커널이 통지해주는 방식이다.

I/O 이벤트 통지 모델 in Linux

select
이벤트 별로 감시할 소켓을 등록하고, 등록한 소켓에 이벤트가 발생하면 그것을 확인하는 방식으로 동작한다. (fd는 1024개 제한)
→ 자체 event loop를 통해 상태 변경을 확인하기 때문에 Synchronous 방식이며 timeout이 nullptr이면 Blocking, timeout이 지정되어 있으면 Non-Blocking이라 할 수 있다.

epoll
select가 매번 모든 fd를 검사한다면 epoll은 검사할 fd만 등록해 놓으면 커널이 fd를 관리하면서 이벤트 발생 여부를 알려주므로 효율이 좋다. fd 개수 제한은 없다.
→ select와 마찬가지로 Synchronous 방식이며 timeout 인자에 따라 Blocking, Non-Blocking으로 구분된다.

I/O 이벤트 통지 모델 in Windows

WSAAsyncSelect
특정 소켓에 대해 통지 받을 이벤트와 통지 받을 때 사용할 메시지를 지정해주면 이벤트가 생길 때 메시지 큐를 이용해 윈도우 메시지 형태로 통지해주는 방식이다. 소켓 이벤트를 다른 메시지 처리하듯 일관성 있게 처리할 수 있는 장점.
→ 운영체제가 I/O 완료 통지를 해주므로 Asynchronous. WSAAsyncSelect에 지정된 소켓은 Non-Blocking으로 동작이 바뀐다. 따라서 Non-Blocking.

WSAEventSelect
윈도우 메시지 모델이 아니고, 네트워크 이벤트가 발생했을 때 이와 연동시킬 이벤트 오브젝트를 등록하는 방식으로 처리된다.
→ select와 비슷하게 폴링하는 방식이므로 Synchronous. 마찬가지로 WSAEventSelect에 지정된 소켓은 Non-Blocking으로 동작이 바뀐다.

2018년 5월 22일 화요일

veamcamp HTML+CSS 재미있게 입문하기 1주차

빔캠프(veamcamp.com)란 곳에서 HTML+CSS 무료강의를 하길래 신청해서 듣기 시작했다. 집에서 가까운 곳이기도 했고, HTML과 CSS에 대해 기초를 쌓고 싶어서 고민없이 신청했다. 빔캠프는 웹디자인 코딩 강의를 하는 곳으로 상수역 근처에 위치해 있다.

신청한 강의는 토요일 오후 5시부터 8시까지 3시간씩 5주 과정으로 HTML과 CSS에 대해 초심자가 꼭 알아야 하는 내용에 대한 강의로 구성되어 있다. 5주간 배울 수 있는 것은 다음과 같다.
a. 박스모델
b. 선택자
c. 블록과 인라인 태그 구분
d. float와 position과 관련된 레이아웃

정규 강좌는 아니고 일종의 맛보기 강좌이기 때문에 깊이 있는 주제를 다루진 않는 듯 하다. 그래서 어찌보면 검색 엔진에서 쉽게 찾을 수 있고 충분히 혼자서 익힐 수 있는 내용이긴 하다. 하지만 이 강의가 괜찮게 느껴지는건 잘 짜여진 틀 안에서 직접 실습해보며 익힐 수 있기 때문에 쉽게 안잊어버릴 것 같단 생각이 든다. 그리고 강사 분 강의 실력이 참 괜찮다. 유머도 있으시고, 완전 초보까지 다 끌고가면서도 정해진 시간안에 나가야 하는 진도를 다 끝마치시는 걸 보면 말이다.

정리 차원에서 간단하게나마 기록은 해두자.

1주차 후기.


개발 환경을 구성했다.

brackets를 설치했고, 자동 들여쓰기와 tab 자동완성 기능을 제공하는 emmetindent guide라는 확장 기능을 설치하였다. atom과의 비교는 잘 모르겠고, sublime text와 비교했을 땐 brackets가 web 개발 환경만큼은 live view를 제공하기 때문에 좀 더 편한듯 하다. 현재 줄을 복사 붙여넣기 하는 단축키(Ctrl + D)와 색상 선택 단축키(Ctrl + E)는 기억해두자.

HTML 문서의 기본 골격과 컨텐츠를 표현하는 태그에 대해 실습하였다.

* 박스 모델: width + height + padding + border + margin.
* HTML은 구조, CSS는 인테리어. 구조를 잡는다는 것은 태그를 이용해 컨텐츠에 성격을 부여하는 것. 각 컨텐츠 요소는 부모-자식의 관계를 갖으면서 확장해 나간다.

. CSS에선 UI Framework에서 흔히 제공되는 center align 속성이 없다. width를 지정해 주고, margin-left: auto; margin-right: auto;와 같이 지정해 주어야 가운데 정렬이 된다. text 요소엔 text-align이란 요소가 있긴 하다.
. padding은 안쪽 여백에 대한 것, margin은 바깥쪽 여백에 대한 공간인데 padding은 컨텐츠의 크기에 영향을 주고 margin은 영향을 주지 않는다.
. border-width, border-style, border-color는 border라는 단축 속성으로 한 번에 표현할 수 있다. border: 5px solid blue; // margin 속성도 마찬가지로 상-우-하-좌 순서로 각 margin을 하나의 속성에 구분해서 지정해줄 수 있다.

2018년 5월 12일 토요일

샤딩, 파티셔닝

Partitioning

파티셔닝은 데이터를 다수의 테이블로 쪼개는 행위를 뜻하는 일반적인 용어(term) 이다. 그리고 파티셔닝은 수직 파티셔닝과 수평 파티셔닝으로 구분된다. 수직 파티셔닝은 하나의 엔티티(table)에 저장된 데이터를 여러 개의 테이블로 분리하는 것을 의미하고, 수평 파티셔닝은 물리적으로 다른 데이터베이스에 데이터를 수평 분할하는 것을 의미한다. (스키마를 복제하고 샤드키를 기준으로 서버를 구분하는 방식.)마지막으로 샤딩은 수평 파티셔닝과 같은 의미로 사용된다.


Sharding

샤딩 (수평 파티셔닝)에 대해 더 알아보자. 샤딩은 서비스를 구성하는 특정 데이터가 서버 1대의 가용 범위를 넘어선다면 고려될 필요가 있다. 가장 기본적인 방법으로 데이터의 range와 서버의 개수를 고려해 0~10000번대로 분류되는 데이터는 하나의 샤드에 저장하고, 10001~20000번대로 분류되는 데이터는 다른 샤드에 저장하는 방식을 고려할 수 있다. 또는 지역 단위로 망원동 데이터는 A 서버에 저장하고, 합정동 데이터는 B 서버에 저장하는 방식을 고려할 수 있을 것이다. 마지막으로 일관된 해싱(consistent hashing) 알고리즘을 적용한 샤딩을 고려할 수 있다


Consistent Hashing

일관된 해싱은 메타 정보를 조회하지 않고 클러스터에서 키가 저장된 서버를 바로 찾아갈 수 있는 방법이다. 키의 해시 값을 구하고, 이 해시 값으로 서버를 찾는 방식인데 서버 목록을 ring 형태로 나열한 뒤 각 서버는 ring에서 각자 맡은 범위만 처리하는 방식이다. 중간에 서버가 추가되거나 삭제되는 과정에서도 일관된 해싱을 보장할 수 있어야 한다.


아마 초기 구현 단계에서 부터 데이터의 트래픽이나 볼륨이 예상 가능하다면 상대적으로 쉽게 샤딩을 디자인에(+stateless 한 구성) 반영할 수 있을 것이고, 그렇지 못한 상황에선 상당히 골치 아픈 일이 될 수 있다. (분산 환경을 고려하지 않았던 서비스 중간에 샤딩을 적용하는 등.) 샤딩을 고려하지 않은 채 디자인된 서비스에서는 join, 트랜잭션, 프로시져 등 데이터를 서버 단에서 처리하기 용이하도록 하는 기법을 사용했을 가능성이 높기 때문에 이러한 서버의 역할을 클라이언트로 내려주는 등의 노력이 필요하다.


2018년 5월 10일 목요일

[ML] Linear Regression

회귀 (regression)

한번 돌아 원래로 돌아오는 것.
회귀는 영구의 유전학자 갤톤이 유전의 법칙을 연구하다 나온 명칭이다. 갤톤은 부모와 자식간의 신장을 조사하였는데, 일반적으로 장신인 부모의 아이는 장신이지만, 그 평균 신장은 부모만큼 크지 않다는 것을 밝혀내었다. 아이의 신장은 항상 일반적인 평균으로 되돌아가는 경향이 있다고 하여, 이것을 평균으로의 회귀 (regression toward to the mean)라 하였다.

회귀의 법칙을 활용한다면 남녀 키의 평균 값을 가지고 알지 못하는 누군가의 키를 그냥 퉁쳐서 예측해볼 수 있을 것이다. 하지만 단순 평균만을 가지고 예측한다면 예측의 정확도는 떨어질 수 밖에 없다. 예측 정확도를 높이기 위해선 키에 영향을 주는 다른 요인을 활용해야만 한다.


회귀 분석

회귀 분석은 독립 변수 X와 종속 변수 y 간의 관계를 정량화 하는 작업이다. 다시 적으면 독립 변수가 종속 변수에 미치는 영향력의 크기를 파악하는 것이다.

회귀 분석을 하면 변수들 사이에서 나타나는 트렌드(trend)를 설명할 수 있다. 단순히 상관 관계의 유무를 넘어 어떤 관계인지 좀 더 자세히 살펴볼 수 있다.

독립 변수와 종속 변수 간에 어떤 관계가 있을지에 대한 여러 가설을 회귀 모델(모형)이라 부르며, 회귀 모델은 크게 트렌드를 나타내는 부분과 통제할 수 없는 오차를 나타내는 부분으로 분리된다. 좋은 회귀 모델을 찾아 변수 간 관계, 경향 등을 파악하는 것이 회귀 분석의 목적으로 이는 결국 오차를 최소화하면서 자료를 설명해줄 수 있는 중심 트렌드를 찾는 것을 의미한다.


회귀 분석의 전제 조건

회귀 분석엔 여러 가정과 전제 조건이 깔린다.
  . 수집된 데이터의 확률 분포는 정규분포를 이루고 있어야 하며 오차항(residuals)은 모든 독립 변수 값에 대하여 동일한 분산을 갖는다.
  . 종속 변수 값들은 서로 독립적이어야 한다.
  . 독립 변수가 여러 개인 경우 독립 변수 간에는 다중공선성이 없어야 한다. (독립 변수간에 서로 영향을 주지 않아야 한다.)
이러한 전제 조건은 사전에 파악하기 어렵기 때문에 우선 데이터를 돌려본 후 사후 검증 과정을 거치는 것이 일반적이다.


선형 회귀

선형 회귀(linear regression)는 종속 변수 y와 한 개 이상의 독립 변수 (설명 변수) X와의 선형 상관 관계를 모델링하는 회귀 분석 기법이다. 쉽게 말하면 주어진 데이터를 잘 설명하는 하나의 대표 직선을 찾는 것이다.

선형 회귀는 종속 변수가 독립 변수에 대해 선형 함수의 관계에 있을 것이라 가정하고 선형 예측 함수(1차 함수)를 사용해 회귀식을 모델링한다. 한 개의 독립 변수에 기반한 경우에는 단순 선형 회귀(Simple linear regression)라 하고, 둘 이상의 독립 변수에 기반하는 경우에는 다중 선형 회귀(Multiple linear regression)라 한다.

선형 회귀에선 최소 제곱법(least square method)을 사용하거나 경사 하강법을 이용해 손실 함수(loss function)을 최소화 하는 방식으로 모델을 세울 수 있다. 이는 모두 오류를 최소화 하는 최적의 회귀 직선을 찾기 위함이다.


최소 제곱법

최소 제곱법은 관측치 y와 예측 결과 값(회귀선) 간 오차의 제곱의 합이 최소가 되는 해를 구하는 방법이다. 분산을 구할 때 편차를 제곱해서 사용하는 것처럼 최소제곱법도 잔차를 제곱해서 사용한다. 양수와 음수가 섞여있으므로 전체적인 오차를 파악하기 힘들기 때문에 부호를 없애는 방법으로 제곱을 선택한다. 절대값을 사용하는 것 대비 부가 효과로 큰 폭의 오차에 대해 보다 더 큰 penalty를 줄 수 있다. 가능한 변동 폭이 적은 회귀선을 도출하기 위함이라 볼 수 있다.


정규화 선형 회귀

정규화(regularized) 선형 회귀 방법은 선형 회귀 계수(weight)에 대한 제약 조건을 추가함으로써 모형이 과도하게 최적화되는 현상, 즉 과최적화를 막는 방법이다. (Normalization이 아니고 Regularization임에 유의하자.)

실제로 데이터를 분석할 때 변수가 굉장히 많은 데이터에 회귀 분석 모델을 적용해야 하는 경우가 자주 발생하는데 변수가 많아질 때 필연적으로 생기는 문제점이 있다.
  1) 모델이 학습 데이터에 오버피팅 되는 경향이 생긴다.
  2) 모델을 해석하기 어려워진다. 만약 어떠한 현상을 설명하는 것이 목적이라면 적은 개수의 변수로 작은 모델을 만드는 것이 권장된다.

정규화 모형은 위 문제를 해소해 준다. 일반적으로 회귀 분석에서의 정규화는 회귀 계수가 커지면 커질수록 모델에 penalty를 주는 방법이다. (모델이 과도하게 최적화되면 모델 계수의 크기도 과도하게 증가하는 경향이 있다.) 따라서 기존 문제에서 오차를 최소화 하는 동시에 penalty에 대한 최소화도 동시에 고려해 주어야 한다.

정규화 선형 회귀의 방법으로 Ridge, Lasso, Elastic Net의 잘 알려진 방법이 있다. Ridge는 각각의 회귀 계수를 제곱한 값의 합에 비례하는 penalty를 주는 모델이다. Ridge 모델은 총 계수의 합을 줄여주는 것에 초점을 맞추고 있으며 가중치 계수를 한꺼번에 축소시키는 특성이 있다. Lasso는 모든 계수를 최대한 0으로 만들어 주는 것에 초점을 맞추고 있으며 일부 가중치 계수가 먼저 0으로 수렴하는 특성이 있다. 마지막으로 Elastic Net은 Ridge와 Lasso를 모두 합친 일종의 하이브리드 모델이라 할 수 있다.

샘플 코드 : http://scikit-learn.org/stable/auto_examples/linear_model/plot_ols.html


[용어 정리]

* 코스트 펑션 vs 로스 펑션 vs 오브젝티브 펑션: https://stats.stackexchange.com/questions/179026/objective-function-cost-function-loss-function-are-they-the-same-thing

* 오차(error): 회귀식의 값과 실제 값(모집단의 모수식으로 부터 나온 값)과의 차이. 모든 데이터를 하나의 회귀식으로 100% 설명할 수 없다.

* 잔차(residual): 표본의 회귀식으로 부터 나온 값. 관측 값의 y와 예측 값의 y 간의 차이. 표본에서는 오차(error) 대신 통계량의 개념을 갖는 잔차(residual)라는 용어를 사용한다.

* 표준화 (Standardization)
수식: (요소값 - 평균) / 표준편차
의미: 평균을 기준으로 얼마나 떨어져있는지를 나타내는 값. 2개 이상의 대상에 대해 단위가 다를 때 같은 기준으로 볼 수 있게 한다. 추가적인 효과로 로그보다는 덜하지만 간극이 큰 데이터의 진폭을 줄여주기도 한다.
→ 키와 몸무게에 대한 표준화, 서로 다른 두 주식 종목에 대한 표준화.

* 정규화 (Normalization)
수식: (요소값 - 최소값) / (최대값 - 최소값)
의미: 전체 구간을 동일하게 설정하여 데이터를 관찰하는 방법. 데이터 군 내에서 특정 데이터가 가지는 위치를 볼 때 사용한다.
→ 주식 시세, 과거 대비 현재 시세의 위치를 파악할 수 있음.

C#, Tuple

Tuple은 간단한 구문을 사용하여 여러 타입의 데이터를 저장할 수 있는 컨테이너로 복사 및 할당에 대한 일관된 규칙을 제공한다. Tuple은 함수의 반환 값으로 여러 개의 값을 전달해야 하거나 읽기 전용 데이터를 임시로 만들어 어딘가로 전달할 때 유용하게 쓰인다. (필요할 때마다 클래스 타입을 추가하는 것보다 손이 덜가기 때문에.)

Tuple은 class 타입이며 복사 및 할당에 대한 일관된 규칙을 제공한다. Tuple에 지정한 값들은 인스턴스가 생성되는 순간 Item1, Item2, Item3, .. 등의 이름으로 자동 매핑된다. (최근 버전에선 Item1, Item2가 아니고 원하는 이름을 지정할 수 있는 듯 하다.)

Tuple은 변경 불가 타입이기 때문에 Tuple을 생성하는 시점에 반드시 Tuple 내의 모든 값을 초기화(지정) 해 주어야 한다. Tuple 인스턴스가 생기고 나면 더는 속성을 변경할 수 없다.

KeyValuePair(이건 struct)와의 성능 비교에서, 객체를 많이 생성하는 경우엔 KeyValuePair가 낫고, 함수 인자 전달 용도에선 Tuple이 빠르다고 한다. Tuple이 인자로 전달된 땐 4바이트 복사만 일어나기 때문.

var tup1 = new Tuple<string, int>("hello", 34);
var tup2 = Tuple.Create<string, int>("hello", 34);

Console.WriteLine(tup1.Equals(tup2)); // True
Console.WriteLine(tup1); // (hello, 34)

// tup1.Item1 = "world"; // Read only, error!

2018년 5월 8일 화요일

[링크] 당신은 몇 년 차?

2009년 혹은 2010년에 작성된 글. '애자일 이야기'라는 블로그를 운영하고 계시는 김창준 님의 글이다.

원문은 여기에.
https://www.ibm.com/developerworks/mydeveloperworks/blogs/9e635b49-09e9-4c23-8999-a4d461aeace2/entry/149?lang=ko

재미있게 읽었다. 아래는 기록하고 싶은 부분들.

경험과 실력은 별개로 봐야 함

소프트웨어 설계와 프로그래밍에 대한 전문성 연구에서 요구 사항 분석 단계의 전문가와 비/준전문가의 차이를 보면, 경험 많은 사람은 경험이 부족한 사람과 비교해 문제 이해에 더 많은 시간과 노력을 기울이는 것으로 밝혀졌으나, 실력이 뛰어난 사람은 실력이 보통 정도인 사람과 비교해 문제 이해에 시간을 적게 쓰는 것으로 나왔다. 그리고 실력이 뛰어난 전문가일수록 의사소통과 협력에 많은 시간을 사용한다는 것도 밝혀졌다. 이렇게 우리는 경력과 실력을 양변에 놓는 항등식의 함정에 빠지면 잘못된 전문가상(전문가의 이미지가 전문가의 현실을 바꾸는 상황)을 갖는다는 것을 알 수 있다.

기량을 향상시키고자 할 때 개선하고자 하는 동기와 빠른 피드백이 중요함

진단전문의는 환자를 한 번 또는 두 번 본 다음, 꽤나 난해한 증세를 해결하기 위해 평가를 내리고, 다음 환자로 넘어갑니다. 그 의사는 환자를 두 번 다시 보지 못하기도 합니다. 저는 최근에 대단히 성공적인 진단전문의를 인터뷰했는데, 그 사람은 판이하게 다르게 일을 하더군요. 그는 상당한 시간을 자기 환자를 확인하는 데에 보내면서, 진단 시에 자신이 무얼 생각하는지 많은 기록을 하고, 자신이 얼마나 정확한지 나중에 확인을 하더군요. 자신이 만든 이 부차적 단계가 그를 자신의 동료들로부터 차별화하는 중요한 점입니다. 이를 통해 그는 자신이 언제, 어떻게 나아지고 있는지 잘 알 수 있습니다. 일반적으로 최고 수준의 퍼포먼스를 내는 사람들은 특별한 테크닉을 활용하는데, 그것은 널리 알려지지도 않고 많은 사람들이 실제로 행하지 않는 것이죠.

채용과 관련된 연구 사례

채용 시 가장 효과적인 예측변수가 무엇이냐에 대한 연구 사례가 있었다고 함. 사람을 뽑을 때 무엇을 우선시하는게 통계적으로 유효한지를 보는 연구다. 잘 뽑았다의 기준은 채용된 후에 실제 직무를 하면서 얼마나 생산적이고 성과를 내는지로 정했다고 함. (프로그래머 채용에 대한 연구는 아니고 성과 측정의 기준은 원문에 나와있지 않다.)

상관성이 높을 것이라 예상했던 변수들이 실제론 낮은 상관성을 보임.
경력 연차와 직무 성과와의 상관성은 0.18
학력(학벌이 아님)의 상관성은 0.1
관심사(interests)는 0.1

상관성이 높게 나왔던 항목은
작업 샘플 테스트 (채용 전 미니 프로젝트) 0.54
IQ와 같은 지능 테스트 0.51
구조화된 인터뷰 (직무에 대해 모든 후보에게 같은 순서의 같은 질문을 하는 인터뷰) 0.51
성실성 성격 테스트 0.41
꼼꼼함 성격 테스트 0.31
레퍼런스 체크 0.26

물론 대학 갓 졸업한 사람 vs 2년차 프로그래머와 같이 초기 경력의 경우 연차의 상관성이 높게 나왔다고 한다.

2018년 5월 1일 화요일

리눅스 기본 명령어.

쉘 프롬프트에서
$는 일반사용자를 뜻하고, #는 관리자를 뜻한다.

리눅스 명령의 기본 구성은 아래와 같다.
명령 [옵션] [인수1] [인수2] ...

명령어에 대해 --help를 붙이면 도움말이 제공된다.
$ date --help

리눅스의 최상위 디렉터리는 '/'고,
개인영역은 '/home/계정' 이다.

윈도우 파일 시스템과 다르게 파일이 어떤 드라이브, 혹은 어떤 파티션에 위치하는지는 신경쓰지 않는다. USB를 마운트 하더라도 media 디렉터리 하위에 붙게 된다.

리눅스의 주요 디렉터리는 다음과 같다.
/bin: 기본적인 명령어 실행 파일
/dev: 물리적인 장치를 지칭하는 파일
/etc: 시스템 관리를 위한 환경 설정 파일
/home: 개인 사용자 홈 디렉터리
/lib: 시스템 프로그램 실행을 위한 각종 라이브러리
/proc: 시스템 실행 정보를 제공하는 proc 파일 시스템
/root: 시스템 관리자 홈 디렉터리
/sbin: 관리자가 사용할 수 있는 중요 관리 명령어
/tmp: 시스템이 사용하는 임시 파일
/usr: 시스템에 사용되는 각종 프로그램이 설치되는 디렉터리
/var: 빠르게 갱신되거나 변화하는 가변 데이터 (로그, 메일 등)

리눅스 기본 명령
> ls: 디렉터리 내용을 표시한다.
ls -a # 숨김파일
ls -l # long format으로 파일 목록 출력
> dmesg: 커널 로그 출력
> clear: 화면 클리어
> alias: 일종의 커스텀 명령어 생성
~/.bashrc 파일에 alias c=clear를 추가하고, source ~/.bashrc로 업데이트 해주면 'c'만 입력해도 'clear' 명령과 동일한 결과를 얻을 수 있는 식이다.
> echo: 문자열 출력
echo "alias c=clear" >> .bashrc # .bashrc 파일에 append, alias를 지정한다.
source .bashrc
> pwd: 현재 경로 표시
> date: 현재 시스템 날짜 출력
ls -l > $(date +%Y%m%d) # ls -l 호출 결과를 파일로 보냄
> wc: 문서의 줄, 행 등 정보 표시
ls /bin | wc -l # /bin 디렉터리의 파일 개수를 센다.
> cat: 파일 내용 표시
> more: 파일 내용을 페이지 단위로 표시
ps -e | more
ls -l | more
> sudo: 관리자 권한으로 실행
> su: 사용자 변경
sudo useradd -d /home/hwang -s /bin/bash -m hwang
sudo passwd hwang
su - hwang
su - # root로 접속
> du: 디스크 사용량 검사 (du -sh)
> df: 디스크 남은 공간 표시 (df -h)
> free: 시스템 잔여 메모리 표시
> mount: 파일 저장 장치를 시스템에 연결
> find: 시스템 내에서 파일을 찾는다
find / -name "*.conf"
find / -name "*.conf" -mtime -180 # 6개월간 수정안된 목록 조회
> grep: 문서 내에서 문자열 패턴을 찾는다.
> ps: 프로세스의 상태를 표시한다.
ps -e # 전체 프로세스 목록.
ps -e | wc -l # 실행중인 프로세스 개수 확인
ps -e | grep cron # cron 프로세스 찾기
ps -f # 부모 PID 확인
grep ^okminseok /etc/passwd
> crontab: 스케줄링. 특정 주기로 원하는 명령어나 스크립트를 실행할 수 있다.
* * * * * my_script.sh # 매 분마다 my_script.sh를 실행. 주기 설정을 순서대로 분, 시, 일, 월, 요일임.
> nohup: 백그라운드 실행
> kill: 프로세스에 시그널을 보낸다.
kill -l # 시그널 종류 목록. 기본 시그널은 SIGTERM(15)
> top: 현재 프로세스 상태 및 자원 사용량 모니터링을 한다. '<'과 '>'로 정렬 기준을 조정할 수 있다. 'bx'는 지정 열 하이라이팅.
> tar: 압축
-c: archive, 압축
-t: view, 목록 확인
-x: extract, 압축해제
-v: verbose
> chown: 파일의 소유자를 변경한다.
> chmod: 파일의 접근권한을 변경한다.
chmod 755 파일명 # 실행 권한 부여
chmod +x 파일명 # 실행 권한 부여
> apt-get: 패키지 설치
* apt-get은 Ubuntu의 패키지 매니저이고 CentOS라면 yum, OS X라면 brew라는 패키지 매니저를 갖는다.
sudo apt-get install openssh-server
sudo service ssh status
> apt-cache: 패키지 검색/표시
sudo apt-cache search vim
> poweroff: 전원끄기
> reboot: 시스템 재시작

라즈베리파이 다루기

라즈베리파이(raspberrypi.org)는 2012년 1월 영국의 라즈베리 파이 재단에서 교육 목적으로 제작 발표한 싱글 보드 컴퓨터다. 지금까지도 가장 성공한 오픈소스 하드웨어 중 하나로 꼽히며 적은 비용으로 꽤 괜찮은 개인 사용 목적의 머신을 구성할 수 있다는 장점이 있다.

한창 인기있었을 때의 RPi2 버전에서 최근엔 RPi3 B+ 까지 출시된 상태다. 하드웨어는 계속 업그레이드 되고 있음에도 가격은 35$를 유지하는 점이 매력적이다. RPi3 부터는 64비트를 지원하며 블루투스, 무선랜이 내장되어 있어 키보드와 마우스, 그리고 라즈비안이 설치된 micro SD 카드만 있으면 일반적인 PC처럼 바로 사용할 수 있다.

라즈베리파이와 자주 비교되는 하드웨어는 비글보드, 인텔 갈릴레오, 엔비디아 젯슨 등이 있지만 개인 DIY 목적에선 라즈베리파이가 가장 나은 선택이 될것으로 보인다. HW 특성이나 비교 관련해서 자세한 내용은 나무위키를 참조할 것. 커뮤니티는 oroca.org가 괜찮아 보인다.
https://namu.wiki/w/%EB%9D%BC%EC%A6%88%EB%B2%A0%EB%A6%AC%20%ED%8C%8C%EC%9D%B4(%EC%BB%B4%ED%93%A8%ED%84%B0)

라즈베리 파이 동작에 필요한 것들.


1. 키보드와 마우스
2. 라즈베리파이를 지원하는 운영체제가 담긴 micro SD 카드
3. 전원 (스마트폰 충전기)
4. HDMI 케이블


라즈베리 파이 주요 지원 운영체제


1. 라즈비안 - 추천. 데비안 리눅스 기반으로 LXDE 데스크탑 환경, 개발 도구까지 포함되어 있어 편리하다. (*LXDE: Lightweight X11 Desktop Environment, 경량 X 윈도우 GUI 환경)
2. 우분투 리눅스
3. 윈도 10 IoT
4. OSMC, OpenELEC
5. RISC OS


라즈비안 설치


1. raspberrypi.org/downloads에서 배포판 이미지를 다운로드 한다.
2. Win32DiskImager를 이용해 micro SD 카드에 설치한다.
3. micro SD 카드를 라즈베리파이 보드에 삽입하고, 전원을 연결한다.
- 초기 접속 계정은 pi/raspberry 이다.


초기 환경설정


1. 터미널에서 sudo raspi-config를 실행하거나, GUI에서 preferences > rasiberry pi configuration 경로를 통해 설정 화면으로 진입할 수 있다.
2. 언어 설정(Change Locale) ko_KR_EUC-KR, ko_KR.UTF-8을 추가한다.
3. 시간 설정(Change Timezone) Asia/Seoul을 지정한다.
4. 키보드 설정(Change Keyboard Layout) 최근 버전에 Korean 배치가 있으니 Korean을 지정한다. 없으면 Generic 105-key로.
5. Interfacing Options에서 SSH와 VNC를 활성화 시킨다. VNC는 GUI 리모트 접속에 대한 설정을 의미한다. VNCViewer 클라이언트를 이용하면 윈도우에서 라즈베리파이로 원격 접속이 가능하다.


한글 설정


1. sudo apt-get update # 최신 정보와 sync를 맞추기 위함.
2. sudo apt-get upgrade # 최신 정보로 실제 업그레이드 수행.
3. sudo apt-get install ibus ibus-hangul # 한글 입력기 설치
4. sudo apt-get install fonts-unfonts-core # 폰트 설치


네트워크 설정


RPi3에선 무선랜을 지원하므로 그냥 우상단의 네트워크 아이콘을 클릭해서 무선 네트워크에 접속하면 된다.
* ifconfig - 유선 설정 / iwconfig - 무선 설정
설정 파일은 /etc/network/interfaces에 있다.


라즈베리파이 GPIO


1. GPIO: 일반적인 용도로 사용 가능한 디지털 입출력 핀. 하드웨어 제어를 위한 신호를 생성하거나 하드웨어에서 들어오는 신호를 받아들이기 위해 사용한다. 터미널에서 gpio readall 명령어를 입력하면 라즈베리파이의 GPIO 핀맵을 확인할 수 있다.
2. 주의점: 라즈베리파이는 내부 3.3V 전원으로 동작되므로 GPIO 핀들도 3.3V 정도로 동작한다. (5V 신호를 사용하고 싶으면 레벨 컨버터가 필요하다.) GPIO 출력인 경우 가능하면 핀 당 3mA 이하, 총합 50mA 이하로 전류 공급을 제한하는 것이 안전하다.
3. GPIO 제어: 간단하게는 파일을 통해 접근하는 방식인 sysfs를 이용할 수 있다. 프로그래밍(응용) 레벨에선 RPi.GPIO 또는 WiringPI 모듈이 주로 쓰인다. 복잡도, 편의 측면에서 파이썬이 나은 선택으로 보인다. 아래와 같이 간단하고 직관적인 인터페이스를 제공하고 있다.

import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
GPIO.setup(PIN_NO, GPIO.OUT)
GPIO.output(PIN_NO, 0)
GPIO.output(PIN_NO, 1)
GPIO.cleanup(PIN_NO)