다른 프로그래밍 언어와 같은 부분이 많아 큰 어려움은 없었지만 타입 변환 등 자바스크립트만의 특성으로 잘 읽어봐야 할 부분이 많았다. 특히 typeofinstanceof 부분은 JavaScript를 더 이해하는데 도움이 되었다.


Chapter 4 표현식과 연산자 Expressions and Operators

표현식 : 값을 구하기 위한 표현 방법

연산자 : 표현식의 구성요소 (값을 반환하거나 연산함)

4.1 Primary Expressions

상수, 문자열 값, 키워드, 변수 레퍼런스 (eg. true, false, undefined)

4.2 객체, 배열 생성자 Object and Array Initializers

  • 객체 : {}
  • 배열 : []

4.3 함수 정의 표현식

var square = function(x) { return x * x; };

4.4 프로퍼티 접근 표현식

expression.identifier  // 식별자가 이렇게 써도 문법에 위배되지 않을 때 사용 가능
expression[expression] // 배열일 때 특히

4.5 구동 표현식 Invocation Expressions

square(10)
Math.min(x, y, z)
foos.sort()
  • 아규먼트의 연산을 먼저 한 후 함수가 실행됨 (in common sense)
  • 실행 가능 객체가 아니라면 TypeError
  • return
  • 함수(OO에선 메서드)가 실행될 때 this

4.6 객체 생성 표현식

var o = new Object()
var d = new Date()
  • 초기화 할 때 생성되는 this

4.7 연산자 미리보기

  • p.62 표 참조. 다른 프로그래밍 언어랑 크게 다른게 없음.
  • typeof, instanceof
  • 문자열 합칠 때와 숫자 계산할 때 둘 다 + 사용
  • 형변환이 자유롭게 발생하므로 유의 "3" * "5" // => 15

4.8 산술 표현식 Arithmetic Expressions

  • *, /, %, +, –
  • NaN
    • 연산자 : 값을 합칠 때 해당 값이 객체이면 3.8.3에서 본 것처럼 toString() 또는 valueOf()로 형변환 시도
  • 비트연산자 : &, |, ^, ~, <<, >>, >>>

4.9 관계 표현식 Relational Expressions

  • ===== : 타입 변환 허용 var point = { x : 10, y: 20 };

    “x” in point // => true

    “s” in point // => false

    var data = [3, 2, 1];

    “0” in data // => true

    // 배열은 값이 들어 있는지 확인하는 것이 아니라 해당 index에 값이 있는지 확인해줌

  • instanceof : 어떤 클래스인지 확인할 때. 상속되는 모든 클래스에 대해 true

4.10 논리 표현식

  • &&, ||, !

4.11 배정 표현식 Assignment Expressions

  • =, +=, -=, *=, /=, %=, <<=, >>=, >>>=, &=, |=, ^=

4.12 평가 표현식 Evaluation Expressions

  • eval(): 하나의 아규먼트를 js 코드처럼 처리해줌.
  • ES5에서 global eval
  • IE 전용 execScript()

4.13 그 외 표현식

  • 3항 연산자(?:) : var age = birthyear > 2000 ? "yong" : "old";
  • typeof : p.82 표 참조
    • “undefined”, “object”, “boolean”, “number”, “string”, “function”, “object”, “<구현한 객체>”
    • null"object" 반환
    • 호출 가능한 객체 callable object 가 정확하게 함수function는 아님. 하지만 typeof에서는 호출 가능한 객체에 대해 “function”을 반환
  • delete
    • ES5 strict에선 못지울 것 지우면 SyntaxError
    • garbage collection이 있으므로 일일이 지워줄 필요는 없음
  • void : 프로토콜에서 사용하는데 (주. 쓰지말자.)
  • , : a=1, b=2, c=3;

짧지 않았던 3번째 챕터인데 깊은 내용은 후반부에 다룬다는 부분이 많았다. 전반적으로 살펴보는 느낌으로 읽으면 좋을 것 같다.


Chapter 3 타입1, 값, 변수 Types, Values, and Variables

이 챕터에서는 다음 세가지에 대해 심층적인 설명을 다룸.

  • 타입 : 문자열, 숫자, 객체 등 값이 어떤 형태의 자료인지를 의미
  • 값 : 3.14, “Hello World” 실제 저장되는 정보
  • 변수 : 값을 나중에 사용하기 위해 이름으로 저장해두는 공간

3.1 숫자

64비트 부동 소수점 포맷

  • 정수 문자열 : 10진수(255), 16진수(0xff), 8진수(0377)
  • 부동 소수점 문자열 : [digits][.digits][(E|e)[(+|-)]digits]
  • 계산 : +, -, *, /, % and Math object (p.33)
  • 무한대 : -Infinity, Infinity, negative 0 (but 0 == -0 => true)
  • NaN : Not-a-number value. 0으로 나누기 등 에러가 발생하는 계산에서 나타나는 값 (비교연산자 못씀. isNaN())
  • 다른 프로그래밍 언어처럼 부동 소수점 처리에 문제가 있으므로 정수 영역으로 쓸 것
  • 일자와 시간 : Date object (p.35), new Date().getTime(). 숫자처럼 비교 가능한 객체

3.2 텍스트

  • 불변(배열같이 0부터 인덱싱), 16비트, 유니코드
  • ” 또는 “”, 개행 또는 이스케이프 시 \ 사용 (p.37, 38)
  • 텍스트 메소드 p.38~
  • 정규표현식 : /hello/g.test("hello world") (챕터 10)

3.3 불린값 Boolean Values

  • true 또는 false
  • undefined, null, ``, -0, NaN, "" => false

3.4 nullundefined

  • undefined : 시스템 레벨, 예측할 수 없어서 마치 에러같은 빈 값, TypeError
  • null : 프로그램 레벨, 일반적 또는 예측 가능한 형태로의 빈 값, no object as an object
  • ==로는 같으나(false이므로) ===로는 다름

3.5 전역객체 The Global Object

JavaScript 해석기(interpreter)가 실행될 때 선언됨 (새로고침하거나.. 할 때 항상)

  • 전역 프로퍼티 : undefined, Infinity, NaN
  • 전역 함수 : isNaN(), parseInt(), eval()
  • 생성자 함수 : Date(), RegExp(), String(), Object()
  • 전역 객체 : Math, JSON

웹브라우저에서는 window, 콘솔에서는 global

3.6 레퍼 객체 Wrapper Objects

기본형 primitive value인 경우 프로퍼티를 가질 수 없으므로 그런 경우 레퍼 객체를 활용할 수 있음. OO로 개발할 때 도움. (Java의 레퍼 클래스와 비슷한듯)

var s = "test", d = new String("test");
s.len = 4, d.len = 4;
console.log(s.len, d.len); // undefined 4
  • String(), Number(), Boolean()

3.7 변하지 않는 기본형과 변하는 객체 참조 Immutable Primitive Values and Mutable Object

References

  • 기본형과 객체의 기본적인 차이인 불변성. 객체는 값이 아닌 참조가 들어있기 때문.
  • 객체를 비교하거나 복사할 때는 유의해야 함. (비교 코드 예시 p.45)

3.8 타입 변환

JavaScript에서의 타입 변환은 완전 유연

  • true로 변하는 값, false로 변하는 값

  • 타입 변환 표 p. 46

  • 비교할 때 타입 변환을 고려할지 안할지. ==, ===

  • 명시적 변환 : 레퍼 객체 또는 x + "", +x",!!x` 활용

  • 진수 변환, 정수 또는 소수 등 parsing parseInt(), (320.329).toFixed(2)

  • 3.8.3 객체를 기본형으로 변환 : valueOf() => toString() => TypeError

  • 객체-숫자 변환과 객체-텍스트 변환 두가지로 문제 발생할 수 있음 typeof(new Date() + 1) // => “string”

    typeof(new Date() – 1) // => “number”

    typeof(+new Date() + 1) // => “number”

3.9 변수 선언

  • var로 선언 : 타입이 따로 지정되지 않음.
  • 중복 선언해도 에러 발생 안함. 선언 안하면 에러남.
  • 항상 var 사용하는걸 권장. => 3.10.2

3.10 변수 스코프 Variable Scope

  • 프로그램 소스코드에서 선언한 변수를 사용할 수 있는 범위. 전역 변수는 전역 스코프를 가짐.

  • 함수 스코프와 호이스팅 Hoisting

    — C에서는 { } 기준의 block scope지만 js에서는 함수 기준의 스코프

    — 함수 중간에 var로 변수선언이 있으면 함수 실행 시 처음에 다 선언처리함 (hoisted)

  • 프로퍼티로서의 변수 : var로 선언하면 삭제 불가능한 프로퍼티로 생성

  • 스코프 체인

    — 변수 확인할 때 스코프 내에 선언되지 않은 경우 상위 스코프로 계속 이동하며 찾음. 끝까지 없으면 ReferenceError

    — 함수 내에 함수를 선언 했을 때

    with 5.7.1, 클로저의 이해 8.6 참고

  • 프로그래밍 서적에서는 흔히 type을 형으로 번역하는데 그냥 영어로 적는다. 

  • 기초적인 부분이긴 하지만 유니코드 값 비교 부분은 잘 살펴볼 필요가 있다. 꼭 자바스크립트가 아니더라도 각 언어에서 유니코드를 어떻게 처리하고 다루는지 알아두면 유용하다. 발생할 수 있는 수많은 케이스가 있는데 그 중 하나로 음악 스트리밍 서비스인 spotify가 사용자명으로 유니코드를 사용해 보안 문제가 발생했었던 사례를 들 수 있다.


    Chapter 2 어휘 구조 Lexical Structure

    어휘 구조는 프로그래밍 언어의 가장 기초적인 문법.

    2.1 캐릭터 셋

    ASCII와 Latin-1를 포함하고 있는 유니코드

    2.1.1 대소문자 구분 – 구분한다

    html은 구분 안하므로 유의

    2.1.2 공백, 줄바꿈, 양식 문자

    공백은 무시됨, 가독성을 위해 사용 (예외 2.5)

    줄바꿈은 단일 행 실행 종료로도 처리됨 (세미콜론 없어도 된다는 말)

    식별자 빼고 LTR, RTL MARK 등 양식 문자를 사용할 수 있음

    2.1.3 유니코드 탈출 문자열

    유니코드 미지원 환경을 위한 유니코드 사용

    \u + 4자리 8진수 주소

    "résumé" === "r\u00e9sum\u00e9" // => true
    

    2.1.4 표준화 Normalization

    유니코드는 같은 글자를 여러 방법으로 표기할 수 있음

    é는 유니코드 문자 하나로 표기할 수도 있고 e + ́ 로도 표시할 수 있음

    console.log("e\u0301", "\u00e9"); // => é é
    console.log("e\u0301" === "\u00e9"); // => false
    

    자바스크립트는 작성된 코드를 이미 표준화 된 것으로 보고 별도로 표준화 처리 안함

    2.2 주석

    /* 블럭주석 */
    /*
    * 블럭주석
    */
    // 인라인 주석
    

    2.3 문자열 Literals

    문자열은 데이터 값을 의미

    number, string(Chapter 3), boolean, 정규표현식(Chapter 10), null, array, object

    2.4 식별자와 예약어

    문자, _, $, 숫자

    첫글자는 숫자 못씀

    일반적으로 아스키 문자와 숫자

    유니코드 식별자도 가능

    2.4.1 예약어

    예약어는 식별자로 쓸 수 없음 – 기본 함수, 타입 등등

    예약어를 무심코 쓰더라도 예약어 썼다고 에러를 출력하므로 외울 필요는 없어 보임

    (변수명을 undefined로 한다거나 -_ 혼난다)

    2.5 선택적 세미콜론

    다른 언어처럼 각각 명령문 끝에 ; 넣음

    세미콜론 대신 줄바꿈으로 생략도 되는데 말이 안되는 줄바꿈은 알아서 인식함

    작성 의도와 다르게 실행되는 예시 – 코드의 명확성을 위해 세미콜론 꼭 쓰자

    놀부님이 진행하는 자바스크립트 스터디 http://on.fb.me/1iEpW0a 에 참여하게 되었다. 커리큘럼에서 제시된 교재를 선택하고 순서대로 공부해나가면 된다. 상당히 세세하고 실질적이라서 전혀 모르는 사람도 공부하기에 좋은 커리큘럼이다. 교재는 JavaScript: The Definitive Guide으로 선택했다.


    자바스크립트 : 고 수준, 동적, 타입 없는 인터프리터 프로그래밍 언어. 객체 지향, 함수형 언어 스타일

    명칭에는 역사적인 배경이 있음. 상표권 문제로 ECMAScript 로 명명. 3와 5 버전이 있음. (4는 건너 뜀)

    클라이언트측 언어의 태생으로 인해 대다수의 언어와 달리 입출력과 같은 API 지원이 약함.

    공부를 위해 개발자 도구를 설치할 것. (Firebug, 또는 각 브라우저 개발자도구)

    1.1 코어 자바스크립트

    Number, string, boolean

    null과 undefined

    object {} 와 array []

    연산자

    함수 선언

    변수로의 함수

    조건문 if 반복문 while for

    Class와 prototype 상속

    1.2 클라이언트측 자바스크립트

    script 태그

    window 객체

    DOM

    이벤트 핸들링 (onclick, onload etc.)

    jQuery

    이후 웹앱, 스크립티드 http, 미디어 그래픽, 스토리지, html5 api 등 심화 학습.

    1.2.1 계산기 예제

    DOM과 ajax, canvas 이용

    요즘 한참 핫(!)한 빅데이터 스터디에 참여하게 되었다. AWS에서는 사실 EMR을 지원하는 등 직접 설치할 일이 없다고 하는데 1EC2 Micro 인스턴스에 Hadoop을 실습을 위해 설치했다. 예/복습 차원에서 간략하게 스터디 내용을 정리해보려고 한다.


    Apache Hadoop

    **Apache Hadoop(High-Availability Distributed Object-Oriented Platform)**은 Apache 재단에서 진행하는 오픈소스 프로젝트로 대량의 자료(빅데이터)를 처리할 수 있는 분산 시스템을 구축할 수 있게 돕는 소프트웨어 라이브러리다. 이 프로젝트는 다음의 모듈을 포함하고 있다.

    • Hadoop Common: Hadoop 모듈을 지원하기 위한 일반적인 유틸리티들
    • Hadoop Distributed File System (HDFS): 어플리케이션 데이터를 대량으로 처리할 수 있게 접근이 가능한 분산 파일 시스템
    • Hadoop YARN: job 스케쥴링과 클러스터 리소스 관리를 위한 프레임워크
    • Hadoop MapReduce: YARN을 기반으로 한 대형 데이터 셋 병렬처리 시스템

    Hadoop HDFS 간단히 알기

    HDFS는 namenodedatanode로 구성되어 있다. Namenode는 HDFS의 파일 구조를 저장하는 영역이고 datanode는 실제 파일을 저장하는 영역이다. 일반적으로 사용되는 NTFS나 FAT같은 파일 시스템은 파일 구조의 위치에 실제 파일이 저장되지만 2HDFS는 그 파일 경로와 실제 파일이 분리되어 각각의 노드에 저장되는 형태이다. Namenode에는 datanode가 어디에 존재하는지 저장되어 있으며, 클라이언트가 해당 파일을 namenode에 요청하면 저장되어 있는 datanode를 알려줘 파일을 내려받을 수 있도록 돕는다. 이와 같이 HDFS는 구조(namenode)와 데이터(datanode)를 분리했기 때문에 데이터의 분산 처리가 가능하다.

    Datanode는 자료를 분산해서 저장함과 동시에 복제본을 담아둬 데이터를 유실했을 때를 대비한다.3

    Namenode는 HDFS의 모든 파일 명령 수행 목록을 Edits에 저장을 한다. FsImage는 Edits를 병합해 기록해둔 파일이다. Secondary namenode는 Namenode를 대체하거나 하진 않고 Edits 파일을 불러다가 FsImage로 병합해 namenode에게 돌려주는 역할을 한다.

    Hadoop MapReduce 간단히 알기

    구조와 데이터를 분산해서 처리한 것과 같이 데이터를 다루는 프로그램도 분산해서 각각의 데이터를 처리할 수 있도록 도와주는 것이 MapReduce이다.

    MapReduce는 Job trackerTask tracker로 구성이 되어 있는데 Job tracker는 Task tracker의 할 일을 관리하는 역할이고 Task tracker는 각 분산된 datanode에서 연산과정을 처리하는 역할을 한다.

    AWS에 Hadoop 설치하기

    설치 준비하기

    AWS에서 인스턴스 생성해서 콘솔로 접속한다. AWS 인스턴스를 시작하는 것은 검색하면 많이 나온다. ubuntu 12.04 LTS를 선택했다.

    $ ssh ubuntu@instance-address
    

    jdk를 설치한다.

    $ sudo apt-get update
    $ sudo apt-get install openjdk-6-jdk
    

    Hadoop을 아파치 다운로드 사이트에서 찾아 내려받고 압축을 해제한다.

    $ wget http://apache.mirror.uber.com.au/hadoop/common/hadoop-1.2.1/hadoop-1.2.1.tar.gz
    $ tar xvfz hadoop-1.2.1
    $ cd hadoop-1.2.1
    

    Hadoop 환경 설정

    Hadoop은 Java 기반이므로 사용할 환경의 경로를 지정해야 한다. conf/hadoop-env.sh을 열어 경로를 지정한다.

    $ vim conf/hadoop-env.sh
    

    JAVA_HOME의 주석을 지우고, jdk의 경로를 정해준다.

    # Set Hadoop-specific environment variables here.
    
    # The only required environment variable is JAVA_HOME.  All others are
    # optional.  When running a distributed configuration it is best to
    # set JAVA_HOME in this file, so that it is correctly defined on
    # remote nodes.
    
    # The java implementation to use.  Required.
    export JAVA_HOME=/usr/lib/jvm/java-6-openjdk-amd64/jre
    
    # Extra Java CLASSPATH elements.  Optional.
    # export HADOOP_CLASSPATH=
    

    Pseudo-Distibuted로 동작할 것이므로 각각의 configuration을 작성해준다.

    core-site.xml에서 fs.default.name 프로퍼티는 namenode가 동작하는 서버를 적어준다. secondary namenode, datanode, task tracker는 이 프로퍼티를 참고한다.

    $ vim conf/core-site.xml
    

    파일에서 아래 부분을 추가한다.

    <configuration>
        <property>
            <name>fs.default.name</name>
            <value>hdfs://localhost:9000</value>
        </property>
    </configuration>
    

    hdfs-site.xml에서 dfs.replication 프로퍼티는 복제 개수를 의미한다. 이 숫자가 3이면 동일한 데이터를 3개로 중복으로 저장해 유실을 방지할 수 있다.

    $ vim conf/hdfs-site.xml
    

    파일에서 아래 부분을 추가한다.

    <configuration>
        <property>
            <name>dfs.replication</name>
            <value>1</value>
        </property>
    </configuration>
    

    mapred-site.xml에서 mapred.job.tracker 프로퍼티는 task tracker를 위해 job tracker가 동작하는 서버를 적어준다.

    $ vim conf/mapred-site.xml
    

    파일에서 아래 부분을 추가한다.

    <configuration>
        <property>
            <name>mapred.job.tracker</name>
            <value>localhost:9001</value>
        </property>
    </configuration>
    

    SSH 설정하기

    각각의 node와 tracker끼리 데이터를 주고 받을 때를 위해 ssh key를 등록해준다.

    $ ssh-keygen -t rsa -P ""
    # 경로는 기존에 생성한 키가 없다면 기본 경로로 해도 된다.
    $ cat /home/ubuntu/.ssh/id_rsa.pub >> /home/ubuntu/.ssh/authorized_keys
    # 추가한 ssh key를 허용된 키로 등록해준다.
    

    키가 제대로 설정되었는지는 다음의 명령어로 확인해볼 수 있다.

    $ ssh localhost
    # 이러면 localhost에 다시 접속된다.
    $ exit
    

    Hadoop 실행하기

    $ pwd
    /home/ubuntu/hadoop-1.2.1
    

    Hadoop을 실행하기 이전에 namenode를 초기화한다.

    $ bin/hadoop namenode -format
    

    그다음 start-all.sh를 실행한다.

    $ bin/start-all.sh
    starting namenode, logging to /home/ubuntu/hadoop-1.2.1/libexec/../logs/hadoop-ubuntu-namenode-ip-10-240-106-45.out
    localhost: starting datanode, logging to /home/ubuntu/hadoop-1.2.1/libexec/../logs/hadoop-ubuntu-datanode-ip-10-240-106-45.out
    localhost: starting secondarynamenode, logging to /home/ubuntu/hadoop-1.2.1/libexec/../logs/hadoop-ubuntu-secondarynamenode-ip-10-240-106-45.out
    starting jobtracker, logging to /home/ubuntu/hadoop-1.2.1/libexec/../logs/hadoop-ubuntu-jobtracker-ip-10-240-106-45.out
    localhost: starting tasktracker, logging to /home/ubuntu/hadoop-1.2.1/libexec/../logs/hadoop-ubuntu-tasktracker-ip-10-240-106-45.out
    

    namenode, datanode, jobtracker, tasktracker가 순서대로 실행되는 것을 확인할 수 있다. 현재 실행되고 있는지 확인하려면 jps로 jvm에서 구동되고 있는 프로세스 항목을 확인할 수 있다.

    $ jps
    10379 NameNode
    11044 TaskTracker
    10852 JobTracker
    11192 Jps
    10562 DataNode
    10753 SecondaryNameNode
    

    종료는 stop-all.sh를 실행하면 된다.

    $ bin/stop-all.sh
    

    Hadoop Mode

    Hadoop은 아래 세가지의 모드로 설치할 수 있다.

    • Local (Standalone) Mode
    • Pseudo-Distributed Mode
    • Fully-Distributed Mode

    위에서 진행한 방식은 Pseudo-Distributed Mode로 하나의 서버에서 namenode, datanode, job tracker, task tracker를 모두 운용하는 모드다. 진짜(?) hadoop은 3번째 모드라고 하니 다음 글에선 3번째 모드로 진행하는 방법을 알아볼 것이다.

    Footnotes

    1. 잘 모른다;;

    2. 내부적으로 어떻게 동작하는지는 잘 모름;

    3. 이 복제 수를 hdfs-site.xml에서의 dfs.replication 프로퍼티로 제어한다.

    색상을 바꿔요

    눈에 편한 색상을 골라보세요 :)

    Darkreader 플러그인으로 선택한 색상이 제대로 표시되지 않을 수 있습니다.