2017년 2월 19일 일요일

[clojure] Udemy 클로저 강의를 듣고

이 언어는 나에게 많은 시련을 준 언어이다.
물론 자바를 처음 배울 때 처럼 아침부터 저녁까지 공부한 것은 아니지만 참으로 나의 머리의 한계를 시험하는 언어였다.
클로저를 처음 배우려고 했던 이유는 폴 그레니엄 때문이었다. 내가 일단 이 사람을 어떻게 접하게 되었는지를 적어야 겠다.
나는 문예창작학과로써 서울에 올라온 이후 항상 서점에 갔다.
삼성동에서 학원을 다닐 때에는 코엑스 지하 1층에 있는 영풍문고를 갔다. 매일매일 저녁을 먹지 않고 혹은 저녁 9시에 학원이 끝났을 때, 나는 영풍문고에서 나의 무지 혹은 나의 미래에 대한 불안감, 거기서 오는 허기짐을 문고에서 채웠다.
아무것도 모르면서 계속 읽었다.
그 중에 [해커와화가]라는 책이 있었다.
제1장을 읽고, 다음장을 읽으려 할 때, 문고가 닫는다는 알림과 음악이 흘러나오기 시작했다. 나는 그 책을 사서 집으로 가져가 전부 읽었다.
그의 주장에는 확신이 있었고, 또 그 확신이 허세가 아니라는 것을 이 책 하나만으로 짐작할 수 있었다.
나는 그의 홈페이지를 들어가보았다. 그는 리스프형 언어 Arc를 소개하고 있었다.
리스프형이 무엇인지 궁금하여 lisp에 대해 찾아보기 시작했다.
그리고 scheme를 한 번 사용해보았다.
common lisp도 한 번 만져보았다. (정말... 만져만 보았다)
내가 클로저를 공부한 이유는 다름이 아니라. 내가 보기에 한국 책이나, 외국 원서나 clojure에 대한 책이 더 많아 보였기 때문이다.
꽤나 많은 책을 보았지만 아직도 clojure에 대해 익숙하지 않다. 내가 일로써 사용하지 않아서 그런 것 같기도 하다.
아직 나는 클로저에서 async에 대해서는 전혀 모른다.(구경만했을뿐...)
병렬프로그래밍이라하면 atom, refer 정도 사용할 뿐일 듯 싶다.
한국 책이던, 외국 책이던 정보가 부족한 것은 참으로 안타까운 듯 싶다. 그래서 사람들이 클로저를 사용하는 듯 싶다.
그나마... 자바와 연결이 되어 있어서, nslookup이라던가. 여러 네트워크 프로그래밍에 자바의 메소드를 사용하는 경우가 있는 것같다.
나는 이제 클로저에서 벽에 부딪힌 느낌이다. 뭐 아는 것도 없는데 벽이라니... 그래서 기초라도 제대로 다지자고 Udemy에 있는 강의를 구매했다.

나름 괜찮았던 것 같다. 하지만 더 많은 정보가 있으면 좋을 텐데... 일단 리스프형 언어에 대해서도 아직 이해가 부족한 상태에서 미지의 세계로 나아가려니 참으로 답답하지 짝이없다.


그래도 고민으로 끝나지않고 계속 나아갈 것이다. 이 길이 망하는 길이라 할지라도
배움은 새로운 곳을 나아가기 위한 것이 아니라
같은 곳에서 새로운 것을 바라보기 위한 것이라 믿으니까.
어느날 다시 되돌아와도...
난 달라져 있으리라

2017년 2월 18일 토요일

[java][byte] 0xff 누구냐 넌!

제목에만 적어놓고 언젠가 적어야지 적어야지 했던 글을 이제야 적는다.
자바를 사용할 때 가끔 0xff를 사용해야 할 때가 있다. 없다고? 음... 그렇다면 당신 대신 누군가 해준 것이니 모른다는 것에 감사하시길...

혹시 unsigned int와 singed int를 아는지? 아아 아주 단순한 문제이니 대답을 해주겠다.
unsigned int : 사인(부호)이 안되어있는 int값
signed int : 사인(부호)이 있는 int값
좀 더 자세히 말하면 부호가 있는 int값과 없는 값 둘로 나뉜다. 그렇다면 자바에서 사용하는 int는 무슨 값일까?

???
모를 수도 있고 알 수도 있다. 비전공자인 나로썬 뭔말인가 싶었다. 하지만 다 정보처리기사에 나오니 걱정하지말라. 누가 물으면 이렇게 말해라.
'그거 정보처리기사에서 다 공부했죠.'
자바에는 int건 byte건 unsigned란 없다. signed만을 (이렇게 해서 설계를 잘했다고 하는 강의도 본 적이 있는데 난 허접이라 잘 모르겠다.) 사용한다. 맞다. 부호가 있는 숫자를 사용한단 말이다. 부호가 없는 int는 사용하지 않는다. 뭐야? 그럼 우리가 알 필요가 없잖아??
유감스럽게도 아니다
왜냐하면 세상은 unsigned int로 이루어진 것들이 꽤나 있기 때문이다. 일단 그렇게 사용하던 코드들이 있고 가장 중요한 것은 이 값은 바이트 타입으로 받았을 때이다.
한 번 바이트 타입으로 127 이상으로 값을 넣어보자.
public static void main(String[] args) {
  byte[] a = new byte[] {127, 0, 0, 1};
  byte[] b = new byte[] {128, 0, 0, 1};
}
a는 되고 b는 안된다. 삶과 죽음은 종이한장 차이라더니, 1의 차이가 프로그램을 아예 실행할 수 없게 만들고 있다.
왜그럴까?
바로 자바는 항상 부호가 있는 숫자이기 때문이다.
바이트는 8비트다. 8비트이면 256개를 표현할 수 있는데, 왜 128이 안된다는 것일까?
잘 생각하자 우리는 부호가 있는 값을 이용한다.
256을 반으로 뚝 잘라라


128 | 128 오!! 되잖아!!! 라고 말 할 줄 알았다. 여기서 한 놈은 1을 빼야한다.
왜? 0을 누군가는 표기해야 하니까.
지금은 그래서 0000 0000 이놈이 0을 표현하게 되는데 이 0이 누구꺼냐는 거다.
결론을 말하면 자바 바이트 타입은 -128 ~ 127 이렇게 표현할 수 있다. 그러니 128은 표현할 수 없는 존재가 되는 것이다.
public static void main(String[] args) {
  byte[] b = new byte[] {(byte)128 , 0, 0, 1};
  System.out.println( (byte) 128 );
}
이거 마이너스가 뜬다. 왜냐하면, 128은 int다. 그걸 바이트로 내가 지금 강제로 형변환을 했다. 128은 2의 7승이다. 그 말은 1000 0000 이다.

일단 맨 앞에 1이 있으면 부호가 음수이다.

public static void main(String[] args) {
  byte[] b = new byte[] {(byte)128 , 0, 0, 1};
  System.out.println( (byte) 128 );
  System.out.println((byte) 128 & 0xff);
}
바로 우리가 알아봐야 할 0xff 누구냐넌! 이놈은 이렇게 생겼다. 쟤는 16진수라는 거다.
잠깐 나가지말고 들어보라. 정말 별거 아니니까!!!
0x는 16진수 앞에 붙는 기호라고 하고.
f는 15을 뜻한다.
f가 두개다. 이것 이런 말이다. 15*16^1 + 15*16^0 이거 한번 계산기를 돌려보자.
System.out.println(15*16 + 15*1);
이건 255가 나온다. 255? 어디서 많이 들어 본 것 같지 않은지? 맞다. 우리 네트워크 설정할 때 많이 사용한다. 바로 그 때!!!! 사용되고 있을 지도 모르는 놈이 0xff이다.

여튼 이놈을 이용해서 &(and)연산을 하면 부호가 없는 없는 그냥 숫자가 나올 것이다. (왜?)
잘 생각해보자. 255는 일단 부호가 있는 숫자에서 255라는 숫자가 나온것이다.
그러면 잘 생각해보자.
기호가 없는 255는 1111 1111 이다. 기호가 있는 255는? 무조건 앞이 0이다. 게다가 255는 int라니까? 부호가 있는 32비트다. 32비트!!!
0000 0000 0000 0000 0000 0000 1111 1111
0xff의 정체이다. 자 그런데 어떻게 저 (byte) 128 & 0xff 가 어떻게 되는거지?
자!! 이제 얼마 안남았다.
1111 1111 1111 1111 1111 1111 1111 1111 1000 0000
0000 0000 0000 0000 0000 0000 0000 0000 1111 1111 (and) 연산 실시
----------------------------------
0000 0000 0000 0000 0000 0000 0000 0000 1000 0000
이러면 이제, 부호가 마이너스가 아니라! 부호가 플러스인 128라는 숫자가 된다.
휴... 금방 끝날 줄 알았는데... 하... 힘들었다.


이 글이 정말 서툴지만 누군가에게는 많은 정보가 되길 바랍니다. 그리고 잘못 적은 내용을 지적해주신 분께 감사의 뜻을 전합니다. ^^