심심해서 nginx에 대해서 검색하고있었는데 비기너스 가이드 beginners_guide가 번역된곳이 없는거같아서 번역해본다.

영어실력이 미천하니 참고로만 봐주시면 좋겠다.

원본 링크 http://nginx.org/en/docs/beginners_guide.html

글 작성일 2021.06.08

목차

  • 시작, 멈춤, 리로딩 설정
  • 설정파일(컨피그파일) 구조
  • 정적파일(Static content) 제공
  • 간단한 프록시 서버 만들기
  • FaxtCGI Proxing 세팅

이 가이드는 nginx에 대한 기본적인 소개화 함께 nginx를 이용해서 수행할 수 있는 간단한 작업에 대해서 서술하고있다. 글을 읽는 사람의 시스템에 이미 nginx가 설치 되어있다고 가정하고 설명을한다. nginx가 아직 설치되지 않았다면 ** 인스톨 페이지 ** 를 참조하도록하라. 이 가이드는 nginx를 시작하는법과 멈추는법, 설정(configuration)을 리로드 하는법, 설정파일의 구조 설명, nginx가 정적 컨텐츠(static content)를 제공하도롱 설정하는법에 대한 설명, nginx를 프록시 서버로 설정하는법, FastCGI 애플리케이션으로 세팅 하는법에 대해 설명한다.

nginx는 하나의 마스터 프로세스와 몇개의 워커 프로세스를 가진다. 마스터 프로세스의 주된 목정은 설청파일을 읽고, 수행하는것과 워커프로세스를 관리하는것이다. 워커 프로세스는 실제 요청을 수행한다. nginx는 워커 프로세스 사이의 효율적인 요청(request)분배를 위해서 이벤트 기반 모델, OS 종속적인 메카니즘을 사용한다. 워커 프로세스의 숫자는 설청 파일에 정의되어있고 주어진 설정량 만큼으로 고정될수 도 있고 사용 가능한 CPU 코어 숫자에 따라서 자동으로 조정될 수 도 있다. (자세한 사항은 워커 프로세스 를 참조하라)

nginx와 모듈들의 동작 방식은 설정파일에 정의되어있다. 설정파일의 디폴트 이름은 nginx.conf이고, /usr/local/nginx/conf, /etc/nginx, /usr/local/etc/nginx의 경로에 위치한다.

시작, 멈춤, 리로딩 설정 Nginx Start / Stop / Configuration 리로드

nginx 시작을 위해선 실행 가능한 파일을 실행시켜야한다. 일단 nginx가 실행되면 -s 옵션을 이용하여 실행파일을 호출해서 제어할 수 있다.
아래와 같은 문법을 사용하면된다.

nginx -s signal

signal은 아래 중 하나가 될 수 있다.

  • stop -- 빠른 종료(fast shutdown)
  • quit -- 적절한 종료(graceful shutdown)
  • reload -- 설정파일 리로드
  • reopen -- log 파일 재 오픈

예를 들어서 워커 프로세스들이 현재 수행중인 요청을 완료할때가지 기다린 후 nginx프로세스를 종료하길 원한다면 아래와 같이 명령어를 실행하면된다.

nginx -s quit

|위 명령어는 nginx를 실행시킨 계정과 같은 계정에서 실행해야 동작한다.|

설정파일의 변화는 nginx에 리로드 명령어를 보내거나 재시작 하기 전까지는 적용되지 않는다. 설정파일을 리로드 하기 위해선 아래의 명령어를 사용한다.

nginx -s reload

마스터 프로세스가 설정을 리로드 하라는 신호를 받으면 마스터 프로세스는 새 설정의 문법 검사(syntax validity)를 수행하고 새로운 설정을 적용하려고 시도한다. 설정 적용에 성공하면 마스터 프로세스는 새로운 워커 프로세스를 실행시키고, 이전 워커 프로세스들에게는 종료 메시지를 보낸다. 설정 적용에 실패하면 마스터 프로세스는 설정을 롤백하고 이전 설정으로 작업을 진행한다. 종료 메시지를 받은 이전 워커 프로세스들은 새로운 컨넥션을 받는것을 중지하고 현재 요청을 완료한 후 종료된다.

요청(signal)은 kill같은 Unix툴에 의해서 전송될 수 도 있다. 이경우 요청은 주어진 Process Id를 참조하여 직접 프로세스에 전달된다. nginx의 마스터 프로세스의 process ID는 default로 nginx.pid 파일에 적혀저있고, 기본 경로는 /usr/local/nginx/logs 또는 /var/run에 있다. 예를들어 마스터 프로세스의 process ID 가 1628일 경우 nginx를 적절한종료(graceful shutdown)하기위해서 아래의 명령어로 QUIT 요청(signal)을 보낼 수 있다.

kill -s QUIT 1628

실행중인 nginx 프로세스를 리스트화 해서 보기위해서는 ps유틸을 사용할 수 있다.

ps -ax | grep nginx

nginx에 요청을 보내는 방법에 대한 더 자세한 정보를 원한다면 Controlling nginx 문서를 참조하라

설정파일(컨피그파일) 구조 Configuration File's Structure

nginx는 모듈로 구성되어있고, 각 모둘들은 설정파일에 명시된 지시(directives) 따라 컨트롤된다. 지시(directives)들은 간단한(simpmle) 지시 들과 블럭 지시들로 나뉘어진다. 간단한 지시는 스페이스(공백)로 나뉘어진 이름과 파라미터로 구성되어있고 마지막에 세미콜론(;)으로 끝난다. 블럭 지시는 간단한 지시와 같은 구조로 되어있으나 세미콜론으로 끝나지않고 중괄호({})로 둘려싸여진 추가적인 지시(instructions)들의 셋을 가지고있다. 블럭 지시는 중괄호 안에 다른 지시를 가지고 있을 수 있고, 이를 컨텍스트(context) 라고 부른다.(ex, events, http, server, location).

설정파일 의 컨텍스트 밖에 위치한 지시들은 main컨텍스트로 간주된다. event 와 http 지시는 main 컨텍스트에 위치하고, server 컨텍스트는 http 컨텍스트, location 컨텍스트는 server 컨텍스트에 위치한다.

# 표시 뒤의 글자들은 주석이된다.

정적파일(Static content) 제공 Serving Static Content

웹서버의 중요한 역할은 (이미지나 정적 html같은)file을 제공하는것이다. 우리는 요청에 따라서 적절한 위치에서 파일을 제공하는 예제를 구현해볼 것이다.
HTML파일은 /data/www에서 제공하고, 이미지 파일은 /data/images 에서 제공하도록 하자. 이렇게 하기위해선 설정파일을 수정해야한다. http블럭에 있는 server블럭에 두 경로를 세팅해보자.

먼저 /data/www 디렉토리를 만들고 index.html 파일을 만들어서 적절한 글자를 좀 써두자. 그리고 /data/images 디렉토리를 만들고 적절한 이미지 몇개를 넣어두자.

다음으로 설정파일을 열자. 디폴트 설정파일에 이미 server 블럭예제가 들어있다. 대부분 주석처리가 되어있다. 이제 모든 블럭의 주석처리하고 새로운 server 블럭을 만들어보자.

http {
    server {
    }
}

일반적으로 설정파일엔 몇개의 server블록이 포트번호와 서버 이름으로 구별되어있다. nginx가 어떤 서버가 요청을 수행할지 결정하면 서버브럭 내에 정의된 위치 지시문(location directives)의 파라미터에 대해 리퀘스트 헤더에 지정된 URI를 테스한다.

아래의 location블럭을 server블럭에 추가해보자.

location / {
    root / data/www;
}

이 location블럭은 리퀘스트의 URI와 비교할 "/" 프리픽스를 지정했다. 매칭되는 리퀘스트에서 URI는ㄴ root 지정된 root 경로를 추가하게된다. 즉, /data/www를 추가하여 요청된 파일을 로컬 파일 시스템의 경로로 연결한다. 매칭되는 location 블럭이 여러개 있다면 nginx는 가장 긴 프리픽스를 선택하게된다. 위의 location블럭은 프리픽스의 길이가 1이기때문에 다른 모든 location블럭이 일치되지 않는 경우에만 사용되게 된다.

이제 두번째 location 블럭을 추가해보자.

location /images/ {
    root /data;
}

위 블럭은 리퀘스트가 /images/로 시작되는 경우에 매칟된다. (/images/로 시작되는 요청은 location / 에도 매칭 되지만 /의 길이가 더 짧기때문에 /images/로 매칭된다.)

server블럭의 결과는 아래와 같을 것이다.

server {
    location / [
        root /data/www;
    }

    location /images/ {
        root /data;
    }
}

이 블럭은 이미 스탠다드 포트인 80포트의 요청을 리슨(listen)하는 서버의 설정으로 동작하게된다. 그리고 로컬 머신에서 'http://localhost/"에 연결할 수 있게 된다. /images/로 시작되는 URI 리퀘스트에 대한 응답으로 서버는 /data/images 디렉토리의 파일을 전송해줄것이다. 예를 들어서 "http://localhost/images/example.png" 리퀘스트에 대한 요청으로 nginx는 /data/images/example.png 파일을 전송해줄것이다. 만약에 해당 파일이 없다면 nginx는 404에러를 넘겨준다. URI가 /images/로 시작되지 않는 요청에대해서는 /data/www 디렉토리로 매핑한다. 예를들어서 "http://localhost/some/example.html" 이라는 요청을 받으면 nginx는 /data/www/some/example.html 파일을 전송한다.

새로운 설정 파일을 적용하기위해서, 아직 nginx를 실행하지 않았다면 시작하도록하고, 이미 시작했다면 reload 시그널을 nginx의 마스터 프로세스에 보내주면 된다.

nginx -s reload

만일 예상대로 동작하지 않는 경우엔 access.log파일과 error.log파일에서 원인을 찾을 수 있다. 해당 파일은 /usr/local/nginx/logs 또는 /var/log/nginx 디펙토리에 있다.

간단한 프록시 서버 만들기 Setting Up a Simple Proxy Server

nginx가 자주 사용되는 방식 중 하나는 프로식 서버로써 사용하는것이다. 프록시서버란 리퀘스트를 받은 후 프록시된 서버로 해당 리퀘스트를 전달해주고, 프록시된 서버가 돌려준 응답을 다시 요청한 클라이언트에게 돌려주는 서버이다.

이제 우리는 기본적인 프로식서버 설정을 할 것이다. 이 프록시 서버는 로컬 디렉토리에서 이미지와 파일 리쿼스트만 받고 다른 모든 요청들은 프록시(된) 서버로 넘긴다. 이 예에서 두 서버 모두 하나의 nginx인스턴스에 정의될 것이다.

먼저 프록시(된) 서버를 만든다. nginx의 설정 파일에 아래의 내용을 추가해서 server블럭 하나를 더 만든다.

server {
    listen 8080;
    root /data/up1;

    location / {
    }
}

이제 이코드로인해서 8080포트를 리슨 하는 단순한 서버가 만들어졌다.(이전엔 listen이 없었기때문에 스탠다드 포트인 80을 사용하고 있었다.)
이 서버는 모든 리퀘스트를 로컬 파일 시스템의 /data/up1 디렉토리로 매핑한다. 해당 디렉토리를 생성하고 index.html 파일을 넣어두자. root는 server 컨텍스트에 위치해 있다는 점을 기억해두자. 이런 root는 location블럭이 root를 가지고 있지 않을경우 사용된다.

다음으로 이전섹션에서 사용한 server 설정을 사용해자. 해당 설정을 수정해서 프록시 서버 설정으로 변환해보자. 첫번째 location 블럭 안에 프로토콜과 함께 proxy_pass 명령을 만들자. 이름과 프록시 될 서버의 포트를 파라미터로 설정해둔다. (우리의 예제에서는 http://localhost:8080이다)

server {
    location / {
        proxy_pass http://localhost:8080;
    }

    location /images/ {
        root /data;
    }
}

우리는 두번째 location 블럭을 수정할 예정이다. 현재는 /images/ 프리픽스를 가진 요청은 /data/images 디렉토리에 매핑되고있다. 이제 요청에 일반적인 파일 확장자를 가진 요청이 있는경우 매칭되게 만들기 위해서 location 블럭은 아래와 같이 변경된다.

location ~ \.(gif|jpg|png)$ {
    root /data/images;
}

파라미터는 정규식이다. URI가 .gif, .jpg, .png 로 끝날경우 모두 매칭된다. 정규식은 반드시 ~ 로 시작해야한다. 이제 일치하는 리퀘스트는 /data/images 디렉토리에 매핑되게 된다.

nginx가 요청을 수행하기위해서 location 블럭을 선택할때 먼저 location 명령어가 특정한 프리픽스를 가지고 있는지 확인한다. 앞서 말한것처럼 가장 긴 프리픽스를 가진 location을 기억하고있고, 정규표현식을 체크한다. 만일 정규표현식에 매칭되는 location이 있다면 해당 로케이션을 선택하고 없는 경우엔 기억하고있던 location을 선택한다.

우리가만든 프록시 서버의 설정을 아래와 같다.

server {
    location / {
        proxy_pass http://localhost:8080;
    }

    location ~ \.(gif|jpg|png)$ {
        root /data/images;
    }
}

이 서버는 .gif, .jpg, .png로 끝나는 요청을 필터링하고 (URI를 root명령어의 파라미터로 추가해서 )/data/images 디렉토리로 매핑할 것이다. 그리고 다른 모든 요청은 이미 설정해놓은 프록시드 서버로 전달한다.

새로운 설정을 적용하기위해서 nginx에 리로드 시그널을 보내야한다. 이전 섹션에서 사용한 명령어를 사용한다.

nginx엔 프록시 서버 설정에 사용가능한 다양한 설정 명령어들이 있다.

FaxtCGI Proxing 세팅 Setting Up FastCGI Proxying

nginx는 리퀘스트를 FastCGI 서버로 라우팅 하기위해서도 사용된다. FastCGI서버는 어플리케이션을 실행하는 다양한 프로그래밍 언어와 프레임워크로 만들어진 서버를 말한다.

FastCGI 서버와 함께 사용하는 대부분의 nginx 설정은 proxy_pass 명령어 대신 fastcgi_pass명령어를 사용한다. 그리고 fastcgi_param명령어를 이용해서 FastCGI 서버에 파라미터를 전달한다. FastCGI서버가 localhost:9000으로 접근 가능하다고 가정해보자. 이전 섹션에서 기본으로 사용한 프록시 설정을 변경해보자. proxy_pass 명령어를 fastcgi_pass명령어로 변환하고 파라미터를 localhost:9000으로 변환한다. PHP에서는 스크립트 이름을 정의하기 위새허 SCRIPT_FILENAME 파라미터를 사용한다. 그리고 QUERY_STRING 파라미터를 이용해서 리퀘스트 파라미터를 전달한다. 변경된 설정은 아래와 같다.

server {
    location / {
        fastcgi_pass  localhost:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param QUERY_STRING    $query_string;
    }

    location ~ \.(gif|jpg|png)$ {
        root /data/images;
    }
}

이제 이설정이 서버가 스태틱 이미지 요청을 제외한 모든 요청을 FastCGI프로토콜을 통해서 프록시된 서버인 localhost:9000으로 보내게된다.

반응형

코틀린 시작하기

코틀린의 특징

  • Java와 형태는 다르나 의미가 유사한 문법을 가지고있기때문에 Java개발자라면 쉽게 학습이 가능하다.
  • 클래스 상속 없이 클래스에 도메인 특화 편의 메소드 추가가 가능하고, 오리지날 클래스의 메소드터럼 사용할 수 있다.
  • 델리게이션을 지원해서 상속보다 더 좋은 디자인이 가능하다. 델리게이션은 타입 안정적으로 사용할 수 있다.
  • if-else 문 대신 argument-matching문법을 사용할 수 있다.
  • 이미 존재하는 함수를 확장하는것이 쉽게 가능하다. 기본 파라미터 기능이 있다.
  • 명시적 인자 사용이 가능하다.
  • 연산자 오버로딩이 가능하다.
  • 우아하고, 표현력이 강하고, 간결하다.
  • C스타일의 프로시저, 스칼라 스타일의 스크립트, Java같은 객체지향형 코드, 스몰톡/얼랭과 같은 함수형 스타일 코드 모두 사용 가능하다.
  • 코루틴과 컨티뉴에이션으로 비동기 프로그래밍 영역에서 혁신을 이끌고 있다.

코틀린이 좋은 이유(와 나의 생각)

  • 다양한 프로그래밍 패러다임
    • 객체지향,함수형, 절차지향, 스크립트, 비동기 프로그래밍 등 다양한 프로그래밍 페러다임을 제공하기때문에 그중 상황에 맞는 방식을 사용하면된다.
    • 보일러 플레이트 코드가 없다.
    • 더 적은 코드로 동일한 일을 할 수 있다.
  • 타입 추론으로 사용하는 정적 타입
    • 강력한 타입 추론을 해주기때문에 시간낭비할 필요가 없다.
    • 타입 추론이 명확하지 않은 경우 개발자에게 타입 명시를 요청한다.
    • 널러블 / 널불가 타입이 구분되어있다.
  • 풀스택 개발을 위한 히나의 언어.
    • 한번의 코드 작성으로 백엔드, 모바일, 네이티브, 웹어셈블리 등의 코드로 컴파일(혹은 트랜스파일)이 가능하다.
    • ( 가능하긴하나 아직 적극적으로 사용하긴 조금 어려운 부분이 있지 않은가 하는 생각이 든다.)
  • 자연스럽고 우아함
    • 보일러플레이트 코드가 필요 없다.
    • 세미콜론이 옵셔널이다
    • 인픽스 어노테이션 사용이 가능하다.

코틀린 설치 및 사용

  • 인텔리J를 사용중이라면 함게 설치되어있다.
  • 별도로 설치를 원하면 https://kotlinlang.org 에서 다운로드 및 설치할 수 있다. 자세한 설치방법은 공식 홈페이지를 참고하도록하자.

설치 확인

cli에서 다음과 같이

kotlinc-jvm -version

본인의 경우는
info: kotlinc-jvm 1.4.31 (JRE 15.0.2+7)
이렇게 출력이 나왔다.

우리가 늘 하는 Hello World 만들기

적절한 폴더에 hello.kt라는 파일을 만들고 아래와 같이 코드를 넣어본다.

//hello.kt
fun main() = println("Hello World")

cli로 실행시키기

kotlinc-jvm hello.kt -d hello.jar

위 명령어를 실행시키면 hello.kt 코틀린 코틀린코드를 Java바이트 코드로 컴파일시키고 hello.jar를 만들어둔다.
jar를 java툴을 이용해서 실행시키면된다.

java -classpath hello.jar HelloKt

hello.kt는 main함수만 가지고있고, 클래스가 아니기때문에 코틀린 컴파일러가 자동으로 확장자를 제거한 파일 이름을 가지고 Kt라는 접미사를 추가한 클래스이름을 만든다.

실행결과는 당연히
Hello World가 나온다.

classpath cli옵션을 열거하지않고, jar옵션으로 실행 가능하다. main()함소를 찾을때 코틀린 컴파일러가 jar 파일에 Main-Class 매니패스트 어트리뷰트를 추가한다.

java -jar hello.jar

현재는 코틀린 스탠다드 라이브러리를 사용하지 않았기 때문에 실행이 잘 되지만 코틀린 스탠다드 라이브러리의 클래스와 함수들을 사용하는 경우 java툴로만 실행한다면 java.lang.NoClassDefFoundError예외가 발생하면서 실패한다. 이를 방지하기위해서는 kotlin-stdlib.jar파일을 클래스패스에 추가해줘야한다.

kotlinc-jvm hello.kt -d hello.jar
java -classpath hello.jar:$KOTLIN_PATH/lib/kotlin-stdlib.jar HelloKt
//위도우인경우 %KOTLIN_PATH% 를 사용, 콜론(:)이 아닌 세미콜론(;)으로 구문해야한다. 등록된 환경변수를 사용하면된다.

ide로 실행하기

코틀린 공식 홈페이지 및 각 ide의 홈페이지와 라이브러리를 참고하면 될거같다. 여기서는 굳이 언급하지 않도록하겠다.

REPL실험

cli에서 kotlinc-jvm 이라고 입력하면 REPL이 실행된다.
아래와같이 조금 사용해보자.

//kotlinc-jvm
Welcome to Kotlin version 1.4.31 (JRE 15.0.2+7)
Type :help for help, :quit for quit
>>> 7 + 5
res0: kotlin.Int = 12
>>> val list = listOf(1,2,3)
>>> list.map{ it * 2}
res2: kotlin.collections.List<kotlin.Int> = [2, 4, 6]
>>>

종료할땐 컨트롤D 를 사용하거나 :quit 라고 입력한다.

REPL에선 이미 존재하는 코드를 불러와서 실행시킬수도 있다.

kotlinc-jvm

Welcome to Kotlin version 1.4.31 (JRE 15.0.2+7)
Type :help for help, :quit for quit
>>> :load hello.kt
>>> main()
Hello World!
>>>

이렇게 REPL에선 존재하는 코드를 컴파일 없이 실행할 수 있다.

스크립트로 실행하기

코틀린은 스크립트로 사용가능하다. 여타 스크립트에 비해서 좋은점이라면 스크립트를 위해 따로 문법 공부를 할 필요가 없다는 점이 있을것이고, 코틀린 스크립트는 문법 오류가 있는 경우 스크립트 실행 전에 실패를하기때문에 컴파일 후 칠행하는것 만큼 안전하다.

연습을 위해서 디렉토리에서 .kts 확장자를 가진파일을 리스팅 하는 스크립트를 만들어보자.

//listktsfile.kts
java.io.File(".")
    .walk()
    .filter { file -> file.extension =="kts" }
    .forEach { println(it) }

지금까지 작성한 코틀린 파일과 별반 타이가 없다. 차이점이라면 확장자가 kts라는것 뿐이다.
이 코드는 JDK의 java.io 패키지의 File 클래스를 사용한다. 그리고 코틀린이 해당 클래스에 추가한 확장 함수를 사용한다.
현재 디렉토리에 있는 모든 파일중 파일명이 kts로 끝나는 파일만 걸러내서 잡고 해당 파일의 경로를 출력한다.

스크립트 실행을 위해선 kotlinc-jvm 커맨드를 사용한다. -script옵션을 통해서 컴파일 대신 스크립트로써 즉시 실행시킨다.

kotlinc-jvm -script listktsfiles.kts

Unix-Like 시스템을 사용한다면 kotlinc-jvm -script라는 접미어 대신 셔뱅(shebang)을 사용하면된다.

greeting.kts

#!/ust/bin/env kotlin-jvm -script
println("hello")

실행을위해 chmod +x greeting.kts 명령어로 파일에 실행권한을 주고 아래의 커맨드라인을 통해 스크립트를 바로 시킬 수있다.

./greeting.kts

시스템에 따라 /usr/bin/env 대신 kotlinc-jvm이 위치한 전체경로를 써줘야 하는 경우도 있다.

다른 타깃으로 컴파일하기

코틀린은 여러개의 타깃으로 컴피일이 가능한 언어이다.

  • 안드로이드
  • javascript로 트랜스파일
  • 네이티브 타깃(iOS, Linux, MacOS, Windows 등 네이티브 타겟)
  • WebAssembly

어떤 옵션을 선택해야할까?

코틀린은 실행시킬때 특정 옵션 설정을 강제하지 않기때문에 개발자의 요구사항과 선호도에 따라 실행옵션을 선택하면된다.
아래는 옵션 선택시 고려해야할 사항이다.

  • JVM에서 실행시키거나 Java또는 다른 언어와 함께사용하는경우 --> kotlinc-jvm을 이용한다.
  • 여러개의 코틀린 파일을 통합해 하나의 코틀린 프로그램으로 실행시켜야한다 -> kotlin툴을 이용한다.
  • 시스템레벨 / 백엔드 태스크 수형해야한다 -> 스크립트

정리

코틀린의 특징에 대해 알아보았고, 간단한 코드를 작성해보았다. 다음번엔 코틀린의 특징을 좀더 자세하게 알아보고 좀더 많은 코드를 작성해본다.

 

영진닷컴 - 다재다능 코틀린 프로그래밍 - 스프링 분철선택

COUPANG

www.coupang.com

쿠팡 파트너스 활동을 통해 일정액의 수수료를 제공받을 수 있습니다.

반응형

'웹프로그래밍 > Kotlin' 카테고리의 다른 글

[Kotlin] data class와 주의사항  (0) 2024.12.02
[KOTLIN] CLASS  (0) 2023.02.25
[코틀린KOTLIN 정리]0. 들어가며  (0) 2021.06.02

앞으로 코틀린에 대한 정리 글을 좀 올려보려합니다. 
정리는 영진닷컴에서 출판한 다재다능 코틀린 프로그래밍 서적을 기반으로 제가 이해한 내용을 정리합니다. 

 

 

 

 

영진닷컴 - 다재다능 코틀린 프로그래밍 - 스프링 분철선택

COUPANG

www.coupang.com

쿠팡 파트너스 활동을 통해 일정액의 수수료를 제공받을 수 있습니다.

반응형

'웹프로그래밍 > Kotlin' 카테고리의 다른 글

[Kotlin] data class와 주의사항  (0) 2024.12.02
[KOTLIN] CLASS  (0) 2023.02.25
[코틀린 KOTLIN 정리]01.코틀린 시작하기  (0) 2021.06.02

+ Recent posts