반응형

 배열이란 같은 종류의 데이터들 일렬로 저장하는 자료구조이다. 

배열에 저장된 각 데이터들은 번호(index)를 가지고 있다.

하지만 이러한 배열만으로는 비효율적이거나 한계가 있는 작업이 있기 때문에 동적배열이나 연결 리스트 등과 같은

자료 구조를 만들어 사용한다. 

(동적배열이든 연결 리스트든 모두 기본적으로 배열을 이용하여 만들어낸 자료구조이다.)




동적배열(Dynamic Array) 이란?

 

 동적 배열이란 크기가 고정되지 않은 배열을 의미한다. (이름 그대로 단순하다!)

보통 우리가 흔히 말하는 배열은 동적(Dynamic)의 반대인 정적(Static) 즉, 정적배열을 의미한다. 정적배열은 크기가 고정되어 있어 데이터를 크기 만큼만 저장할 수 있다.

대표적으로 C++ 의 vector 나 자바의의 ArrayList 등이 있다.




동적배열이 필요한 이유


 동적배열은 이름에서 나타나듯이 배열의 크기를 동적으로 늘려서 사용하고 싶을 때 필요하다. (이유도 단순하다!)

배열은 크기가 고정해야 되기 때문에 이를 해결하기 위해 동적배열이 고안된 것이다.

처음부터 자신이 사용할 배열의 크기를 알면 좋겠지만 크기를 너무 크게 잡으면 메모리가 낭비되고, 그렇다고 크기를 작게 잡으면 매번 배열을 새로 만들어서 기존의 배열을 옮겨 담아야 해서 번거롭다.




동적배열의 시간복잡도


1. 특정 위치의 데이터를 반환하거나 변경하는 작업을 시간복잡도 O(1) 에 처리할 수 있다. 

(배열과 공통)


동적배열은 배열을 이용하여 구현되어 있기 때문에 데이터들이 메모리의 연속된 위치에 저장되어 있고, 각 데이터들은 번호(Index)를 가지고 있다. 그래서 특정 위치의 데이터를 호출하거나 변경하는 O(1)에 처리할 수 있다.



2. 배열의 크기를 변경하는 resize() 연산을 시간복잡도 O(N) 에 처리할 수 있다.

resize() 연산은 새로운 배열을 만들어 기존 배열의 데이터를 복사하는 작업이기 때문에 기존 배열의 크기에 비례하여 시간이 소요된다. 그렇기 때문에 resize() 연산은 O(N)에 처리 된다.


3. 데이터를 배열의 맨 끝에 추가하는 append() 연산을 시간복잡도 O(1)에 처리할 수 있다.

동적배열의 append() 연산이 O(1)에 처리 될 수 있는 것은 동적배열의 재할당 전략 덕분이다. 
동적배열의 재할당 전략은 새로운 배열의 크기를 기존 배열의 크기를 2배 만큼 늘리는 것이다.
예를들자면 동적배열은 1 -> 2 -> 4 -> 8 -> 16 순으로 메모리 크기를 늘려 가는 것이다.
만약에 append() 연산 마다 새로운 배열의 크기를 기존 보다 1 씩 늘려 데이터를 저장하면 매번 resize() 연산을 해야하기 때문에 
append() 연산의 시간복잡도가 O(N)이 되어 선형이 되버린다. 
그래서 아래 그림과 같이 메모리에서 할당받은 크기(capacity) 만큼 데이터 수(size) 가 채워졌을 때 기존 배열 크기 보다 2배 만큼의 크기를 메모리에서 할당받아서 저장 공간을 넉넉하게 만든다. 그러면 그 다음부터 append() 할 때 데이터를 빈 공간에 순서대로 채워넣으면 되기 때문에 append()을 O(1)에 처리 할 수 있는 것이다.





그런데 여기서 두가지 의문점이 생긴다. 

첫번째 . 
   결국은 배열이 꽉 찼을 때 append()를 하면 resize() 를 해야하는데 어떻게 append() 의 시간복잡도가 O(1)이 되는걸까? 

두번째.
   그리고 왜 새 배열의 크기를 기존 배열의 크기 보다 2배를 늘리는 것일까?

두 의문점에 대한 답은 append()의 평균 수행시간에 있다. 
먼저 기존 배열이 꽉 찼을 때 append()를 하면 resize() 를 해야하기 때문에 그 순간은 시간복잡도가 O(N)이 된다. 
하지만 시간복잡도를 평균적으로 보면 한번 씩 resize()를 한다고 해도 append() 의 시간복잡도는 O(1) 이 된다.
또한 이때 새 배열의 크기를 기존 배열의 크기 보다 2배씩 늘려야 append()의 평균 수행시간이 O(1) 이 된다.

예를들어 배열을 재할당할 때 크기를 상수만큼 늘린다고 가정해보자.

K = resize() 호출 수 (재할당 횟수)
M = 재할당하는 배열의 크기 
N = append() 호출 수 ( 저장할 데이터 개수)

처음에 빈 배열을 만들어서 데이터를 N개 만큼 추가 한다( append()를 N번 호출한다. )
기존 배열의 공간이 가득차면 resize() 를 호출해야하고 새 배열의 크기는 기존배열 보다 M 만큼 늘어나기 때문에

resize() 호출수(K) =   이 된다. 


즉, 데이터를 1,000(N) 개를 넣을 때 배열의 재할당 크기를 10(M) 이라고 하면

  해서 재할당(K)은 100번 일어난다. 

(데이터를 10개 넣고나면 배열이 가득 차서 배열의 크기를 새로 늘려줘야 하기 때문)

여기서 M 은 상수 이기 때문에 N 이 커질수록 M 값이 미치는 영향은 작아진다.

따라서 resize() 의 시간복잡도(K)는 O(N) 이 된다. 

( M이 10이든 100이든 상수는 결국 시간복잡도에 영향을 주지 못한다. 


배열을 재할당 할 때 마다 새 배열에 복사되는 데이터의 수는 각 M개, 2M개,  ,  개 이다.

N개의 데이터를 넣으면서 복사되는 데이터의 수를 모두 더하면  (1+2+3++K)M 이므로

 이 된다.


즉, N번의 append() 를 수행하는 데에는 수행시간이 총   만큼 소요되고 이를 N 으로 나누어서 평균을 내면 O(N) 이 되어 append() 평균 수행시간은 O(N) 이 되버린다.


하지만 배열의 크기를 기존 배열 크기의 2배씩 늘리게 되면 

배열을 재할당 할 때 마다 새 배열에 복사되는 데이터의 수는 각 1개, 2개, 4개, 8개,  ,  개 이다.

N개의 데이터를 넣으면서 복사되는 데이터의 수를 모두 더하면 1+2+4+8+  + 이므로

등비수열의 합 공식 에 따라 이 된다. 


( 1 은  이기 때문에 K번 재할당 했으면 마지막은 K-1 번째가 된다. )



그림으로 이해해보자면 배열의 크기가 2배씩 증가하기 때문에 마지막인 1 번째 부터 K-2 번째 까지의 합이 K-1 번째 값과 

거의 같다. 

K-1 번째 resize() 의 시간복잡도는 O(N) 일 것이기 때문에 결국은 1 번째 부터 K-1 번째 까지 데이터를 복사한 수행시간은

기껏 해야 O(2N) 일 것이고 결국 append()의 총 수행시간은 O(N) 이 된다.

따라서 배열의 크기가 2배씩 증가할 때 append()의 평균수행 시간은 O(N)을 N으로 나눈 O(1)이라고 할 수 있다.



반응형

'IT 정보 로그캣 > CS' 카테고리의 다른 글

[알고리즘] 재귀함수  (0) 2019.04.13
[알고리즘] 비트마스크란  (0) 2019.03.23
[자료구조] 연결 리스트  (0) 2019.03.16
[자료구조] 스택, 큐, 데크  (0) 2019.03.07
빅오 표기법 (big-O notation) 이란  (0) 2019.03.04
반응형

 자료구조는 자료(데이터)를 효율적으로 접근하고 수정하기 위해 자료를 조직,관리,저장하는 방법을 의미한다.

자료구조가 필요한 이유는 상황에 따라 데이터를 다루는데 시간과 메모리를 효율적으로 사용해야 때문이다.

자료구조는 형태에 따라 크게 선형 자료구조와 비선형 자료구조로 나뉘어 진다. 

선형 자료구조란 자료를 구성하는 데이터들이 직선 형태로 순차적으로 나열되어 있는 구조로 전후 데이터들 간에 일대일( 1:1 ) 관계이다.

 

 

< 선형 자료구죠 >

 

 

비선형 자료구조란 하나의 자료 뒤에 여러개의 자료가 존재할 수 있는 구조로 전후 데이터들 간에 1:N 의 관계를 가진다.

 

 

< 비선형 자료구조 >

 

 

자료구조에서 선형구조에는 대표적으로 스택(stack), 큐(queue), 덱(deque), 리스트(list) 등이 있고,

비선형구조에는 트리(tree), 그래프(graph) 등이 이다. (실제로는 더 다양하다.)

 

 

< 자료구조 종류 >

 

 

 

스택(stack) 이란?

 

  스택은 한 쪽 끝에서만 데이터를 넣거나 뺄 수 있는 후입 선출 (Last In First Out , LIFO)의 자료구조이다.

쉽게 생각하면 stack 의 뜻처럼 쌓는걸 의미한다 생각하고, 하노이의 탑과 같다고 생각하면 되겠다.

 

 

 

큐(queue) 란?

 

 큐는 한 쪽 끝에서 데이터가 삽입되고, 다른 한 쪽 끝으로 삭제 되는 선입 선출(First In First Out, FIFO)의 자료구조이다.

마치 차들이 1차선 터널을 통과하는 것과 같다. queue 의 뜻이 줄을 서서 기다리는걸 의미하니 음식점 앞에 줄서 있는 구조라 생각해도 되겠다.

 

 

 

덱(deque) 이란?

 덱은 스택과 큐가 결합한 자료구조로 양쪽 끝에서 데이터들을 넣고 뺄 수 있다.

 

 

 

자료구조에서는 데이터를 넣는 작업을 push , 자료를 꺼내는 작업을 pop 이라고 한다.

대부분의 프로그래밍 언어에서 표준라이브러리로 스택, 큐, 덱의 구현체를 제공하고 있다.

 

 

 

 

 

 

 

 

 

 

 

반응형
반응형

 컴퓨터 과학(Computer Science) 에서 알고리즘은 어떠한 문제를 해결하기 위한 방법이고,

어떠한 문제를 해결 하기 위한 방법은 다양하기 때문에 방법(알고리즘) 간에 효율성을 비교하기 위해

빅오(big-O) 표기법을 보통 가장 많이 사용한다.

(결국은 알고리즘 공부를 하려면 배워야한다는..)




빅오 표기법 (big-O notation) 이란?

 

 빅오 표기법은 알고리즘의 효율성을 표기해주는 표기법이다. 

쉽게 생각하면 알고리즘 스카우터라 생각하면 된다 :)

알고리즘의 효율성은 데이터 개수(n)가 주어졌을 때 덧셈, 뺄셈, 곱셈 같은 기본 연산의 횟수를 의미한다.

빅오 표기법은 보통 알고리즘의 시간 복잡도와 공간 복잡도를 나타내는데 주로 사용 된다.

(시간 복잡도는 알고리즘의 시간 효율성을 의미하고, 공간 복잡도는 알고리즘의 공간(메모리) 효율성을 의미한다.)

그런데 시간과 공간 복잡도를 나타내는 방법으로는 점근 표기법이라고 해서 

빅오(Big-O), 빅오메가(big-Ω),빅세타(big-Θ) 표기법이 있다.

 

 

그렇다면 세 가지 중 왜 빅오 표기법을 사용할까?

 

 결론부터 말하자면 빅오 표기법은 알고리즘 효율성을 상한선 기준으로 표기하기 때문이다. (알고리즘 효율성은 값이 클수록 즉, 그래프가 위로 향할수록 비효율적임을 의미한다.)

빅오메가는 하한선을 기준으로하고, 빅세타는 상한선과 하한선의 사이를 기준으로 표기한다.

일상의 대화에서 비유하자면 법정 최고이자율이 24% 인데 친구가 사채대출의 이자율을 물어본다.
(이자율이 높을수록 최악의 경우이다.)

하지만 정확한 법정 최고이자율이 생각나지 않는다.

이때 친구에게 빅오 표기법으로 말하자면 사채대출을 받으면 이자율이 30% 안에서 책정 될거야 라고 말하는 것과 같다.

(실제로 정확하진 않지만 대략 30%를 넘지 않을 것을 알고 모든 경우의 수를 포함하도록 말하는 것이다.)

빅오메가 표기법으로 말하자면 이자율이 0% 이상 일거야 라고 말하는 것과 같다. (사실상 의미가 없다.)

빅세타 표기법으로 말하자면 이자율이 0%(하한) 와 30%(상한) 의 사이쯤 이라고 말하는 것과 같다.

(빅세타는 하한과 상한 사이 평균정도의 의미로 쓰인다.)

 여기서 주의할 점은 빅오 표기법이 상한선만 지정했을 뿐 상한선이 꼭 알고리즘 효율성의 최악의 경우는 아니라는 것이다.

예를들어 법정 최고이자율이 24% 라서 사채의 이자율은 24%를 넘을 수 없다. 내가 30% 안이라고 해서 친구가 사채의 이자가 최대 30%까지 될 수도 있겠다고 생각할 필요는 없는 것이다. 이자율이 최악으로 가장 높은 경우인 24% 가 이자율 30% 안에 포함된다는 말일 뿐이다.

 

 

빅오 표기법의 수학적 정의

 

 빅오 표기법이 나타내는 의미는 수학적 정의를 통해 알 수 있다. 점근 표기법 중 빅오 표기법을 보통 가장 많이 사용하기 때문에 빅오 표기법의 수학적 정의 정도만 보고 넘어가자.

빅오 표기법의 수학적 정의는

 

   

 

간단하게 예를들자면

 

은 내가 만든 알고리즘의 시간 효율성(running time) 을 의미하고 충분히 큰 값인 n과 상수 k에 대해

 

 

이라고 가정하면

 

   (  ) 가 성립하는 k 값이 존재하기 때문에 내가 만든 알고리즘  은 빅오 표기법을 사용하여 로 나타낼 수 있다.

 

 

추가적인 이해를 돕기 위해 아래 그래프를 보자.

 

 

 

내가만든 알고리즘의 시간 효율성(running time)을 보여주는 그래프가 이다.

이때  보다 충분히 큰 입력값 n 을 넣었을 때 내가만든 알고리즘 의 running time이 최악인 경우에도 점근 상한선인  을 넘을수가 없다.

이때를 빅오 표기법을 사용하여  이라고 나타내는 것이다.

(위의 예시에서는  )

 

 

 

빅오 표기법의 특징

 

1. 상수항 무시 : 빅오 표기법은 데이터 입력값(n)이 충분히 크다고 가정하고 있고, 알고리즘의 효율성 또한 데이터 입력값(n)의 크기에 따라 영향 받기 때문에 상수항 같은 사소한 부분은 무시한다.

예를들어

 

 와 같이 상수항은 무시하고 표기한다.

 

 

2. 영향력 없는 항 무시 : 빅오 표기법은 데이터 입력값(n)의 크기에 따라 영향을 받기 때문에 가장 영향력이 큰 항에 이외에 영향력이 없는 항들은 무시한다.

예를들어

 

와 같이 영향력이 지배적인  이외에 영향력이 없는 항들은 무시한다.

 

 

 

빅오 표기법 성능비교

 

 빅오 표기법에서 주로 사용되는 표기법은 아래 그래프와 같다.

 

 

그래프에 나와 있는 시간 복잡도의 성능을 비교하면 다음과 같다.

(왼쪽에서 오른쪽으로 갈수록 효율성이 떨어진다.)

                                                           

faster    slower

 

( 상수함수 < 로그함수 < 선형함수 < 다항함수 < 지수함수 )

 

 

 

빅오 표기법 예제

 

 빅오 표기법의 예제는 어떤 것들이 있는지 정도만 외워두고 알고리즘 공부를 해보면서 이해해 나가면 될 것 같다.

 

1. O(1) : 스택에서 Push, Pop

2. O(log n) : 이진트리

3. O(n) : for 문

4. O(n log n) : 퀵 정렬(quick sort), 병합정렬(merge sort), 힙 정렬(heap Sort)

5. O(): 이중 for 문, 삽입정렬(insertion sort), 거품정렬(bubble sort), 선택정렬(selection sort)

6. O() : 피보나치 수열

 

 

 

 

 

 

반응형

'IT 정보 로그캣 > CS' 카테고리의 다른 글

[알고리즘] 재귀함수  (0) 2019.04.13
[알고리즘] 비트마스크란  (0) 2019.03.23
[자료구조] 연결 리스트  (0) 2019.03.16
[자료구조] 동적배열 (Dynamic Array)  (0) 2019.03.14
[자료구조] 스택, 큐, 데크  (0) 2019.03.07
반응형

Node.js 를 사용하기 위해서는 기본적으로 자바스크립트 문법을 알아야 한다.

자바스크립트 문법에는 ECMAScript (ES) 라는 자바스크립트 표준 문법이 있다.

ECMAScript 는 자바스크립트가 다양한 웹 브라우저를 공통적으로 잘 지원하기 위해 생겨났다. 

현재 2019년 1월 기준으로 ECMAScript 2018 (ES9) 이 최신이고, 매번 새로운 버전이 릴리스 될 때

마다 최신 트렌드를 따라가야 한다.

하지만  ES6 문법을 정리하는 이유는 가장 많이 쓰이는 ES5 (2009 릴리스) 에서 ES6 (2015 릴리스) 로 

넘어오면서 문법상으로 많은 변화들이 있었고, 브라우저 지원율도 증가하여 

실질적으로 ES6가 최신 자바스크립트 표준에 가깝다고 볼 수 있기 때문이다.




변수 let 과 const


ES6 이전에는 변수를 var을 사용했는데 이제 let (변수) 과 const (상수) 로 나누어진다.

var 과의 차이점은 var은 전역 범위인 반면 let 과 const 는 선언한 { } 내부 블록에서만 유효하다. 


 function test () {

    let letNumber = 1;

    const constNumber = 1;


    if(true){

        let letNumber = 2;      

        const constNumber = 2; 


        console.log(letNumber);      // 2 출력

  console.log(constNumber);   // 2 출력

    }


console.log(letNumber);      // 1 출력

  console.log(constNumber);   // 1 출력

}




템플릿 리터럴


ES6 에서는 백틱 ( ` ) 을 이용하여 문자열을 + 기호 없이 간단히 처리할 수 있다.

또한 백틱 ( ` ) 안에서는 멀티 라인도 자유롭게 사용할 수 있다.


const id = "myId" ;

const url = `http://noahlog.tistory.com/login/${id}` ;


const message = ` 줄바꿈도 마음대로

  사용이 가능합니다. ` ;




함수의 기본 매개 변수값 지정


ES6 의 함수는 매개변수에 기본값 (default) 을 지정해 줄 수 있다.


function test ( height =10 , width = 20, color = 'green' ) {

...

}




객체 리터럴


ES6 에서는 객체 리터럴의 사용성이 좀 더 간편화 되었다.


var say = function() { console.log("hello"); }


const myObject = {

say,

work() { console.log("do work"); } ,

['name'] : 'noah'

};




화살표 함수


ES6 에서는 축약형 함수인 화살표 함수를 사용할 수 있다. 

특이한 점이 있다면 화살표 함수에서 this 는 함수 자신을 호출하는 객체가 아닌

화살표 함수의 상위 스코프 (scope) 를 호출한다.


const numbers = [ 1, 2, 3, 4, 5 ];


let choice = numbers.map( v => v + 1);    //축약 형태로 return 도 생략 가능


const noah = {

name : "noah",

friend : [ "mimi" ],

printFriends() { 

this.friend.forEach( f => 

console.log(` ${this.name} loves ${f}`)); 

}

};


noah.printFriends();    // 결과값 : noah loves mimi





비구조화 할당 (destructuring Assignment)


비구조화 할당은 배열이나 객체에서 데이터를 편리하게 가져올 수 있게 해준다.


//객체 

const blog = {

owner : "noah",

url : "noahlogs.tistory.com",

getPost() { console.log("ES6 문법 정리"); }

};


let { owner, getPost } = blog;       //각각 blog 객체의 owner , getPost() 의 데이터가 할당




//배열

const pocket = ["coin" , 10 , true];

const [ first , second, third ] = pocket;    //배열의 순서대로 값이 할당




프로미스 (Promise)


프로미스는 자바스크립트의 비동기 처리에 사용되는 객체이다. 

콜백 지옥에서 벗어나게 해주는 유용한 기능이다 :) 

ES8 (ECMAScript 2017) 에서 async/await 이 생겨나면서 프로미스에서 처리할 수 없던 순서 처리를 

할 수 있게 되었다. 필요할 때 사용하면 될 것 같다. 


const connect = new Promise((resolve, reject) => {

//success = resolve , fail = reject 반환 

});


connect.then( (success) => { 

console.log(success);

//성공 한 다음 처리할 작업 

}).catch( (error) => {

console.log(error);

//에러 예외 처리

});






반응형

'IT 정보 로그캣 > Javascript' 카테고리의 다른 글

자바스크립트 정규 표현식  (0) 2020.02.04
[Node.js] npm 이란  (0) 2020.01.04
[Node.js] Node.js 란?  (0) 2019.01.24
반응형

웹 애플리케이션 서버 (WAS, Web Application Server) 를 만들기 위해 Node js 를 선택했다.

선택한 이유로는 개발 생산성 측면과 구조적 측면 (싱글스레드 기반의 비동기 처리 방식) 때문이다.

보통 비슷한 이유로 스타트업 등에서 Node js를 많이 선택한다.

Node js 를 사용하기 전에 어떤 기술인지 부터 알고 사용하자!

 

 

 

Node.js 란?


Node js 는 2009년 Ryan Dahl에 의해 시작된 오픈 소스 노드 프로젝트이다. 

Node.js 공식 홈페이지에 따르면 Node.js 는 Chrome V8 자바스크립트 엔진으로 빌드된 자바스크립트 런타임으로 정의되고 있다.

여기서 Chrome V8 자바스크립트 엔진은 웹 브라우저를 만들기 위한 구글의 오픈 소스 자바스크립트 엔진으로 C++로 만들어졌다. 자바스크립트 런타임이라는 것은 일종의 자바스크립트을 실행하기 위한 프로그램이다 라고 이해하면 될 것 같다.

 

 

 

Node.js 의 특징


Node.js 의 주요한 특징으로는 4가지를 뽑을 수 있다.

 

1. 런타임

2. 싱글 스레드 

3. 비동기 처리 방식 (논블로킹 I/O)

4. 이벤트 기반 ( Event-driven )

 

하나하나 가벼운 주제가 아니므로 여기서는 간단히만 정리하였다.

 

 

런타임 

 앞서 언급했듯이 Node js 는 자바스크립트 런타임이다.

기존 웹 브라우저에서만 실행 가능한 자바스크립트를 Ryan Dahl이 구글이 만든 V8 엔진을 사용하여 다른 환경에서도 사용이 가능하도록 노드 프로젝트를 시작하였다.

Node js 는 다음과 같은 구조로 구성되어 있다.

 

 < Node js 내부 구조 >

 

  • V8 : V8 라이브러리는 Node js 가 V8 C++ API로 제어하는 자바스크립트 엔진을 제공한다. 

  • libuv : libuv 라이브러리는 C 라이브러리로 논블로킹 I/O 작업을 지원하는 역할을 한다. 파일 시스템, DNS, 네트워크, 파이프, 신호 처리, 폴링, 스트리밍, 자식 프로세스를 다룰 수 있도록 지원한다.

  • http-parser : HTTP 파싱에 사용되는 경량화된 C 라이브러리이다. 

  • c-ares : 일부 비동기 DNS 요청을 위해 사용되는 c 라이브러리이다. 

  • OpenSSL : tls 와 cypto 모듈에서 사용되는 보안을 위한 라이브러리이다.

  • zlib : 빠른 압축과 압축 해제를 위한 산업 표준인 라이브러리이다. Node js 에서는 동기, 비동기, 스트리밍 압축과 압축 해제 인터페이스에 사용된다.

 

 

싱글 스레드

 Node js 는 자바스크립트를 기반으로하기 때문에 싱글 스레드만을 지원한다.

실제 Node js 의 프로세스는 여러 스레드를 가지고 있으나 우리가 사용할 수 있는 스레드가 하나라서 싱글 스레드이다.

Node js 가 이해와 사용이 쉬운 이유 중 하나도 싱글 스레드 덕분인 것 같다. 멀티 스레드에 비해 싱글 스레드가 프로그래밍 난이도가 상대적으로 쉽기 때문이다. 

( ..아무래도 일을 시키더라도 직원을 여러 명 관리하는 것 보다 한 명 관리하는게 쉬우니 )

Node js 가 싱글 스레드를 지원하긴 하지만 멀티 프로세스를 지원하기 때문에 코어를 낭비하는 일은 없다.

노드 클러스터나 pm2 등을 이용하여 멀티 프로세스 구현이 가능하다.

 

 

논블로킹 I/O

 Node js 는 싱글 스레드 기반이기 때문에 작업 처리의 효율성을 위해 논블로킹 I/O 방식을 사용한다. 

( ..일손이 한명이니 블로킹 방식으로는 도저히 작업 진행이 안된다. )

오래 걸리는 작업 A를 백그라운드로 보내서 다음 작업 B를 먼저 실행되게 하고, 작업 A는 다시 태스크 큐를 거쳐 호출 스택으로 올라오기를 기다리는 방식이다.

 

 

이벤트 기반(Event-driven)

 Node js 는 이벤트가 발생할 때 미리 지정해둔 작업을 수행하는 방식의 이벤트 기반 모델이다.

이러한 이벤트 기반 모델에서는 논블로킹 I/O 작업을 수행할 수 있도록 해주는 이벤트 루프라는 개념이 존재한다.

구글링했을 때 이벤트 루프에 대한 잘못된 설명이나 오해가 많다고 한다. ( ..역시 공식문서를 봐야한다. )

이벤트 루프 작업 순서는 timer -> pending callbacks -> idle, prepare -> poll -> check -> close callbacks 의 반복이다.

각 단계는 실행할 콜백의 큐(FIFO)를 가진다.

 

< 이벤트 루프 사이클 >

 

  • timer : setTimeout() 과 setInterval() 로 스케줄링한 콜백을 실행한다.

  • pending callbacks : TCP 오류 같은 시스템 작업의 콜백을 실행한다.

  • idle, prepare : 내부용으로만 사용한다.

  • poll : I/O 를 얼마나 오래 블록하고 폴링해야 하는지 계산한 다음 큐에 있는 이벤트를 처리한다.

  • check : setImmediate() 콜백을 호출한다.

  • close callbacks : 소켓이나 핸들이 갑자기 닫힌 경우에 'close' 이벤트를 발생 시킨다. 그렇지 않으면 process.nextTick() 이 실행 된다.

 

 

 

Node js 정리 


 대부분의 플랫폼 혹은 기술들은 자신만의 철학을 가지고 있다. 

Node js의 철학은 "경량화" 라고 할 수 있다. 

경량화된 코어와 모듈을 통해 사용자가 Node js를 쉽게 이해하고 사용하도록 도와주며, 테스트 및 유지 보수를 간단하게 할 수 있도록 도와준다. ( ..Node js는 모듈을 통해 레고를 조립해 나가는 것과 같은 느낌이다. )

하지만 경량화된 만큼 CPU의 연산이 많이 필요한 무거운 작업 보다는 가벼운 작업들을 처리하는데 더 강점이 있다.

 

 

 

 

 

 

 

반응형

'IT 정보 로그캣 > Javascript' 카테고리의 다른 글

자바스크립트 정규 표현식  (0) 2020.02.04
[Node.js] npm 이란  (0) 2020.01.04
[Node.js] ES6 주요 문법 정리  (0) 2019.01.24
반응형

 Swift 에는 클로저 (Closures) 라는 개념이 존재한다.

얼핏 봐서는 코드를 간결하게 짤 수 있게 해주는 기능을 하는 것 같고,

실제로 적용해서 많이 사용해봐야 익숙해 질 것 같은 기능이다. 

클로저는 필수적이라기 보다는 Swift 를 더 잘 사용하기 위한 기능에 가까운 것 같아서

처음 배울 때는 한 번에 완벽하게 이해하고 지나가기 보다 개념 정도와 기본적인 사용법 정도만 알고 지나가면 될 것 같다.




클로저 (Closures) 란 ?


 클로저 란 간단하게 설명하자면 코드 블럭이다. 

함수를 코드들의 모임이라고 설명했었는데, 클로저는 함수 보다 더 포괄적인 개념으로 생각하면된다.

(함수도 클로저의 일종이다.)

다만 Swift 에서는 클로저의 개념이 주로 이름이 없는 함수 (익명 함수)로 많이 활용되는 것 같다.

클로저를 통해 일회성으로 사용 되는 함수를 간결한 형태로 표현하려고 하기 때문이다.

Swift 공식 문서에 따르면 클로저는 세 가지 형태가 있다고 한다.

  1.  이름이 있고, 어떤 값도 획득하지 않는 전역함수 
  2.  이름이 있고, 값을 가지고 있는 함수로 부터 값을 획득할 수 있는 중첩된 함수
  3.  이름이 없고, 주변 문맥에 따라 값을 획득할 수 있는 축약된 문법의 표현 

이렇게 세 가지가 있다고 하는데 말로만 들어서는 이해가 바로 되진 않는다.




클로저 표현법


 클로저의 표현법은 다음과 같다.


{ (파라미터) -> 리턴타입 in 

//코드 작성 

}


 대충봐도 함수와 뭔가 비슷한 느낌이 든다.




클로저의 기본적인 사용법


Swift 공식 문서의 예제를 통해 간단하게 클로저의 기본적인 사용법만 따라해 보았다.

예제는 sorted(by: ) 메서드를 통해 이름 값을 가지고 있는 배열을 알파벳 역순으로 정렬하는 예제이다.

( sorted() 메서드에 대한 정보는 https://developer.apple.com/documentation/swift/array/1688499-sort 참고)




그림을 보면 sorted(by: ) 함수를 클로저 문법을 사용하면 간단하게 표현이 가능하다.

sorted(by: ) 함수 처럼 공통으로 사용되는 함수가 아니라면 지나치게 축약된 표현은 오히려 코드의 가독성을 떨어뜨릴 것 같다.



이외에도 클로저에 대해 값 획득이나 클로저의 참조 타입, Escaping Closures, Autoclosures 에 대한 개념들을

추가로 공부해야한다. 

처음 공부할 때에는 Swift 의 코드를 간결하고 깔끔하게 만드는 것 보다 익숙해지고 많이 사용하는게 더 

중요하기 때문에 추후에 코드들을 많이 접하고 나서 나머지 개념들도 다루도록 해야겠다.












* 해당 포스팅은 스위프트(Swift)4  버전을 기준으로 하고 있습니다.

* 참고 : https://swift.org/ 



 



반응형

'IT 정보 로그캣 > Swift' 카테고리의 다른 글

[Swift 공부] 함수  (0) 2018.12.15
[Swift 공부] 반복문  (0) 2018.11.11
[Swift 공부] 조건문  (0) 2018.11.10
[Swift 공부] 기본 연산자  (0) 2018.11.04
[Swift 공부] 컬렉션 타입이란 ?  (0) 2018.11.03
반응형

개인 클라우드 용도부터 카메라,게임기까지 활용하기에 따라 다양하게 사용될 수 있는 라즈베리 파이에 

대해 알아보겠습니다.





라즈베리 파이 (Raspberry Pi) 란?


 라즈베리 파이(Raspberry Pi)는 영국 잉글랜드의 라즈베리 파이 재단에서 컴퓨터 교육을 위해 

개발되었습니다. (이 편지는 영국에서 시작되어.. 처럼 지겹게 듣는 설명)

쉽게 생각하면 저렴한 미니 컴퓨터라고 생각하시면 됩니다. 

(24시간 내내 켜놔도 전기세도 저렴하게 나옵니다.)






라즈베리 파이 모델 종류


 라즈베리 파이는 2019년 1월 기준으로 모델 종류가 아래와 같습니다.


  • 라즈베리파이 1 A
  • 라즈베리파이 1 A+
  • 라즈베리파이 2 B
  • 라즈베리파이 3 B
  • 라즈베리파이 3 B+
  • 라즈베리파이 zero W (W는 Wireless 의 약자로 와이파이와 블루투스만 지원한다는 의미입니다.)


최신버전은 라즈베리 파이3 B+ 이고 당연히 숫자가 올라갈수록 최신이며, +가 붙은게 더 최신입니다.

라즈베리 파이 제로 버전은 보급형 버전이며 사양이나 크기가 다른 모델 보다 상대적으로 작고 

가격이 더 저렴합니다. 

제로 모델을 제외하고는 가격이 비슷하기 때문에 최신 버전으로 구입하시는게 좋습니다.






라즈베리 파이3 B+ 구성 및 스펙


 현재를 기준으로 라즈베리 파이의 가장 최신버전인 라즈베리 파이3 B+ 모델을 기준으로 설명하겠습니다.

라즈베리 파이3 B+ 모델의 구성은 다음과 같습니다.


출처 : http://www.eleparts.co.kr/goods/view?no=5980692&src=raspberrypi



기본적으로 컴퓨터로 사용하기 위한 CPU 와 모니터연결을 위한 HDMI 포트, 키보드나 마우스 연결을 위한 USB 2.0 포트 (4개 까지 연결 가능) , 통신을 위한 블루투스, 와이파이 모듈 및 LAN 포트 를 갖추고 있습니다. 그외 용도에 따라 사용할 수 있도록 다양한 포트 및 커넥터 등을 제공합니다.




라즈베리파이 공식 홈페이지의 라즈베리파이3 B+ 스펙은 다음과 같습니다.


  • 칩셋(System-on-chip) :  Broadcom BCM2837B0
  • CPU : Cortex-A53 (ARMv8) 64-bit @ 1.4GHz
  • RAM : 1GB LPDDR2 SDRAM
  • 무선 : 2.4GHz and 5GHz IEEE 802.11.b/g/n/ac wireless LAN, Bluetooth 4.2
  • 유선 : Gigabit Ethernet over USB 2.0 (maximum throughput 300 Mbps)
  • 영상 : Full-size HDMI / DSI display port (touchscreen display)
  • 음성 : 4-pole stereo output
  • USB : 4 USB 2.0 ports
  • 카메라 :  CSI camera port
  • SD카드 :  Micro SD port
  • 전원 : 5V/2.5A DC power input
  • GPIO :  Extended 40-pin GPIO header

어차피 현재는 라즈베리 파이3 B+ 모델이 최신이라 주는대로 사용할 수 밖에 없지만 그래도 살펴보자면
스펙에서 유심히 볼 점은 CPU가 쿼드코어 64비트 프로세서라는 것입니다.
또한 블루투스 4.2를 지원하고 USB는 2.0 이라는 것 그리고 MicroSD를  사용한다는 것입니다.
HDD/SSD 등의 저장소를 따로 사용할 수 있지만 운영체제나 기본적인 저장소로 MicroSD 를 사용합니다.
(USB 2.0 이기 때문에 아무리 좋은 HDD/SSD 를 사용한다고 한들 제대로 성능을 내기 힘듭니다.)
 




라즈베리 파이 구입

최근에는 포털에서 검색만해도 쇼핑목록에 쏟아지기 때문에 대충 가격비교해서 구입해도 괜찮지만
그래도 더 안전하게 구입하고 싶다 하시는 분들은 라즈베리 파이 공식 홈페이지 에 들어가서
BUY NOW> 를 누르면 한국의 공식 리셀러가 나오니 해당 쇼핑몰에서 구입하시면 됩니다.
라즈베리 파이 구입하실 때 전원 어댑터 (넉넉히 3100mA 급 정도)와 방열판(발열 심함), 
MicroSD 카드 (최소 16GB 이상), 라즈베리 파이 케이스를 함께 구입하시길 추천드립니다.



반응형

'IT 정보 로그캣 > 하드웨어' 카테고리의 다른 글

[하드웨어] 램(RAM)이란?  (0) 2018.09.06
[하드웨어] CPU란?  (0) 2018.09.04
반응형

 Swift를 제대로 사용하기 위해 함수에 대해서 알아보자.

프로그래밍 언어에서 함수는 특정한 작업을 수행하는 코드들의 모임이다.

어떤 프로그램에서 코드들이 쭉 있다면 그중 일부분을 떼어와서 그룹화 시키고 그 그룹에 이름을 붙여주는 것과 같다.

매번 똑같은 코드를 복붙하는건 귀찮고 비효율적이기 때문에 간단하게 함수명만으로 코드들을 호출하는 것이다.

(항상 말하지만 결국은 프로그래머 좋으라고...ㅎㅎ)


 예전에는 함수를 그날 기분에 따라 함수 또는 메서드로 불렀는데 사실 함수와 메서드는 엄밀히 따지자면 조금 다르다.

함수가 메서드의 상위 개념이고, 보통 전역으로 사용하는 함수를 "함수" 라고 부르고 객체지향 언어에서 클래스,구조체 등의 내부에서 사용하는 함수를 메서드라 부른다. 즉 메서드는 멤버함수를 의미한다.

(메서드를 항상 메소드라 적었는데 표기법도 찾아 봤더니 국립국어원 표준국어대사전에 따르면 "메서드"가 올바른 표기법이라 한다.)




Swift의 함수


 다른 프로그래밍 언어의 함수와 비교하자면 Swift의 함수는 기본적인 형태는 자바나 다른 프로그래밍 언어와 

비슷하지만 함수의 자유도가 비교적 높은 편이다.

자유도가 높다고 한 이유는 함수의 중요한 요소인 매개변수와 리턴 타입 등을 다양한 형태로 사용할 수 있고, 

함수 자체를 매개변수나 리턴 타입으로 사용 하는 등 함수를  다양하게 정의할 수 있기 때문이다.

또한 기본적으로 함수의 오버라이드(재정의), 오버로드(중복 정의)를 모두 지원한다.

Swift는 함수를 선언할 때 func 이라는 키워드를 사용한다.  

리턴타입은 -> 를 사용하고, 리턴은 말그대로 return 이라는 키워드를 사용한다.




Swift의 기본적인 함수 사용법


기본적인 함수 형태는 다음과 같다. 


func 함수명 (매개변수...) -> 리턴 타입

//코드작성

return 리턴 값 

}


이 형태를 기본으로 다양하게 활용이 가능하다. 

다만 리턴 타입이 없는 경우에는 생략해도 되고 [ -> Void ] 를 넣어줘도 된다.




함수의 매개변수 이름과 전달인자 레이블


 Swift 의 함수는 매개변수 이름을 지정해주는 것 뿐만 아니라 전달인자 레이블 이라는 것도 지정해 줄 수 있다.

매개변수 이름은 함수내에서 매개변수를 호출할 때 사용하고, 전달인자 레이블은 함수를 호출해서 사용할 때 변수들을 쉽게 구분하기 위한 용도 정도로 사용한다. 

자바 처럼 함수를 호출하여 매개변수를 넣을 때 별다른 명칭없이 넣고 싶으면 와일드카드 식별자 ( _ ) 를 넣어주면 된다.

( 전달인자 레이블 명을 바꿔도 함수를 오버로드 하여 사용할 수 있다!)





함수의 매개변수 기본값


 Swift의 함수는 매개변수에 기본값을 줄 수 있다. 

그리고 기본값이 지정되어 있는 매개변수는 보통 앞쪽에 배치된다.





함수의 가변 매개변수


 코딩을 하다보면 매개변수가 유동적으로 들어가야하는 경우가 있는데 이 때 가변 매개변수를 사용하면 된다.

가변 매개변수는 함수마다 하나씩만 사용이 가능하고, 가변 매개변수는 배열처럼 사용이 가능하다.




함수의 입출력 매개변수


 프로그래밍 언어를 공부하다보면 call by value 와 call by reference 를 접하게된다. 

call by value 는 값을 복사해서 사용하는 형태이고 call by reference 는 참조로 객체를 전달하는 형태이다.

보통 매개변수는 call by value 로 값만 복사해서 사용하는데 C 언어의 포인터처럼 call by reference 로 참조하고 싶을 때

사용하는 것이 입출력 매개변수이다. 매개변수 타입 앞에 inout을 붙여주면 되고 함수를 호출할 때에는 참조했다는 표시로 

앰퍼샌드(&)를 붙여준다. 입출력 매개변수의 값을 변경하면 참조이기 때문에 할당한 참조의 값도 변경된다.

(애초에 참조가 아니면 함수에서 매개변수의 값을 변경하는게 불가능하다.)





함수 타입 


 Swift 에서 함수는 일급 객체로 함수 자체를 타입을 사용할 수 있다. 

함수를 데이터 타입 뿐만 아니라 매개변수 타입이나 리턴 타입으로도 사용이 가능하다.




 이외에도 함수 안에 함수를 중첩하여 사용하는 등 Swift 의 함수는 다양하게 사용이 가능하므로 

코딩을 하면서 조금씩 자기에게 필요한 형태의 함수를 찾아 사용하는게 좋겠다.






* 해당 포스팅은 스위프트(Swift)4  버전을 기준으로 하고 있습니다.

* 참고 : https://swift.org/ 






반응형

'IT 정보 로그캣 > Swift' 카테고리의 다른 글

[Swift 공부] 클로져 (Cloures) 란?  (0) 2019.01.13
[Swift 공부] 반복문  (0) 2018.11.11
[Swift 공부] 조건문  (0) 2018.11.10
[Swift 공부] 기본 연산자  (0) 2018.11.04
[Swift 공부] 컬렉션 타입이란 ?  (0) 2018.11.03
반응형

 Swift 의 흐름제어 (Control Flow) 에는 조건문과 반복문이 있다. 

조건문에는 IF 문과 Switch 문이 있었고




2018/11/10 - [IT 정보 로그캣/Swift] - [Swift 공부] 조건문




이번에 살펴볼 반복문에는 For-In while 구문이 있다. 

반복문은 이름 그대로 어떠한 작업을 반복하기 위해서 필요한 것들인데 이름에서부터 왜 필요한지 느껴진다. 

코드나 상황을 반복해야할 때 Ctrl + c , Ctrl + v  는 지겹고도 비효율적이기 때문이다. 

(이것도 결국 프로그래머 좋으라고 있는..)




For - In 


 For - In 구문은 우리가 자바에서 사용하던 for - each 구문과 똑같다고 보면된다. 

기존에 사용하던 for ( ~ ; ~ ; ~ ) 형태의 구문이 Swift 에서는 사라졌는데  (Swift 3 부터 없어졌다.) 

아마도 For - In  구문이 더 간단하기도 하고, For - In 구문만으로도 충분하다고 생각한 것 같다.

For - In 구문은 배열, 수의 범위, 딕셔너리 같은 시퀀스를 다루는데 사용한다. 



그림 1 > 배열을 이용한 For - In 








그림 2 > 딕셔너리를 이용한 For - In






그림 3 > 수의 범위를 이용한 For - In ( 따로 시퀀스가 필요없는 경우 와일드 카드 패턴을 이용할 수도 있다.)



 For - In 구문에서 stride(from : 값1 to : 값2 by: 값3 ) 라는 함수를 사용할 수도 있다. stride 함수는 두 수 사이에 특정한 값의 간격을 주어 시퀀스를 사용할 수 있게 한다. 함수를 풀이해보자면 from 의 값1 부터 to 의 값2 까지 by 의 값3 씩 간격을 준다는 의미이다.

 * stride 함수에는 (from : 값1 to : 값2 by : 값3) 와 (from : 값1 through : 값2 by: 값3 ) 의 형태가 있는데 to 를 사용하는 경우에는 마지막값이 포함되지 않고, through 를 사용하는 경우 마지막값까지 포함한다 ( 미만과 이하 의 차이라고 생각하면 된다.)


그림 4 > For - In 구문에 Stride (from : 값1 to : 값2 by : 값3) 함수 사용








그림 5 > For - In 구문에 Stride (from : 값1 through : 값2 by : 값3) 함수 사용





while


 while 구문에는 그냥 while 을 사용하는 것과 repeat - while 을 사용하는 2가지 방법이 있다. 

두개 의 차이는 자바로 비교하면 while 과 do - while 의 차이라고 볼 수 있다. ( 실제로 do 를 repeat 으로 바꾼 것 뿐이다)

 while 은 조건부터 체크하여 조건이 만족할 때에만 { } 안의 코드를 실행 시키지만 repeat - while 은 일단 { } 안의 코드를 한번 실행시키고 그다음 (2회 차) 부터 조건을 체크하여 { } 안의 코드를 실행 시킬지 결정한다.


그림 6 > while 구문









그림 7 > repeat - while 구문

반응형

'IT 정보 로그캣 > Swift' 카테고리의 다른 글

[Swift 공부] 클로져 (Cloures) 란?  (0) 2019.01.13
[Swift 공부] 함수  (0) 2018.12.15
[Swift 공부] 조건문  (0) 2018.11.10
[Swift 공부] 기본 연산자  (0) 2018.11.04
[Swift 공부] 컬렉션 타입이란 ?  (0) 2018.11.03
반응형

 Swift 에도 다른 프로그래밍 언어와 마찬가지로 코드를 짤 때 가장 중요한 흐름제어 (Control Flow) 인 

조건문과 반복문이 있다. 

그 중에 조건문에는  IF 문과 Switch 문이 있는데, 각각 Swift 만의 특징을 가지고 있다. 




IF 문

 

 조건문 중에 하나인 IF 문은 평범하게(?) if ~ else if ~ else 로 사용 된다. 

다만 Swift 의 경우 IF 문의 조건을 입력할 때 소괄호 ( )를 생략할 수 있다. 개인적으로는 습관이기도 하고 코드의 구분이 더 

쉬운 것 같기도해서 괄호를 넣는 편이다.

또 한가지 특징이 더 있는데 IF 문의 조건은 무조건 Bool 타입 (true / false) 만 사용해야한다. 

Swift 에서는 true 와 false 를 1 과 0 의 값으로 사용하지 않기 때문이다. 



그림 1 > IF 문 사용법




Switch 문


 조건문으로 Switch 문도 있는데 Swift 의 Switch 문은 특이점이 많다. 그만큼 활용도가 높다는 뜻이기도 하다.

Swift 공식문서에서도 여러가지 Switch 문의 활용 방법을 소개해주고 있는데 각각 다음과 같다.


1. default 사용 


 Swift 의 Switch 문은 조건의 범위를 모두 포함하고 있어야한다. 이게 무슨 말이냐면 조건에 해당하는 범위가 case 에 모두

포함되지 않으면 default 를 추가하여 여기다가 나머지 조건들을 처리해줘야 한다는 것이다.

예를들어 아래의 그림에서 처럼 조건이 알파벳이라고 가정하면 case 에 있는 "a", "b" 이외의 case 상황은 default 를 사용하여 처리해줘야한다.  다른 말로하면 case 에 a~z 까지 모두 있다면 default 는 없어도 된다.



그림 2 > Switch 문의 기본 사용법



2. break 의 생략과 fallthrough


 Switch 문에서 조건에 소괄호 ( )를 생략할 수 있는건 당연하고, case 의 break 생략도 가능하다. 

자바와 비교하자면 자바의 Switch 문 에서는 break 가 없으면 조건에 맞는 case 부터 그 아래에 있는 

case 의 코드들 까지 모두 실행되지만 Swift 에서는 break 가 없어도 자동으로 해당하는 case 의 코드만 실행해 준다. 

그래서 Swift 에서는 조건에 맞는 case 부터 그 아래에 있는 case 코드들 까지 모두 실행 하려면 fallthrough 를 입력해줘야 한다. 





그림 3 > Switch 문 fallthrough 사용법



3. 범위 연산자 사용


 Swift 의 Switch 문은 case에 범위 연산자도 사용할 수 있다. 그리고 case 에는 비교값을 여러개 넣을 수도 있다.



그림 4 > Switch 문의 범위연산자 사용과 여러 값 비교 법



4. 튜플 (Tuples) 사용과 값 바인딩

 

 Switch 문의 case 에는 튜플도 사용이 가능한데 여기서 끝이 아니라 튜플안에 들어있는 값 대신에 와일드 카드패턴( _ ) 

까지 사용할 수있다. 와일드 카드패턴 이란 언더 바 ( _ ) 를 사용하여 어떤 값의 자리를 대신 채워주는 것이다. 

대신 해당 값 자체는 무시한다.(Swift 에는 와일드 카드패턴 이외에도 다양한 패턴이 존재한다.)

값 자체를 무시하기 때문에 무시된 어떠한 값을 사용할 수 없는 불편함이 있다... 

그래서 이를 해결하기 위해 값 바인딩을 사용하면 된다!

값 바인딩 이란 별건 아니고 와일드 카드 패턴 ( _ ) 대신에 상수를 선언하듯이 [ let 변수명 ] 을 넣어줘서 해당 값까지 사용할 수 있도록 하는 것이다.


그림 5 > Switch 문에서 튜플 사용과 값 바인딩



4. Where 


  Swift 의 Switch 문에서 가장 특이한 점은 Where 을 사용할 수 있다는 것이다. 

Where 은 우리가 sql 쿼리를 사용할 때 보던 것과 비슷한데 case 에 조건을 추가하고 싶을 때 사용할 수 있다.

사용하기에 따라 다양하게 활용할 수 있을 것 같다.



그림 6 > Switch 문에서 Where 의 사용법







* 해당 포스팅은 스위프트(Swift)4  버전을 기준으로 하고 있습니다.

* 참고 : https://swift.org/ 


반응형

'IT 정보 로그캣 > Swift' 카테고리의 다른 글

[Swift 공부] 함수  (0) 2018.12.15
[Swift 공부] 반복문  (0) 2018.11.11
[Swift 공부] 기본 연산자  (0) 2018.11.04
[Swift 공부] 컬렉션 타입이란 ?  (0) 2018.11.03
[Swift 공부] 튜플(Tuple)이란?  (0) 2018.10.28

+ Recent posts