[MongoDB] 해킹된 후 보안 설정 관련

DB|2019. 12. 23. 19:57

라즈베리파이에 토이프로젝트로 끄적끄적 돌리고 있는 서비스들이 있습니다.

아직 외부에는 거의 오픈하지 않아(하나는 카카오 채널을 통해 접속 가능하도록..^^;;)

개인적으로 저만 사용하고 있었죠

(디비는 MongoDB를 사용중이였습니다.)

 

그런데 주말에 접속해보니 서비스중 하나의 페이지가 정상적으로 나오지 않았습니다.

 

"응..? 매일마다 정해져있는 정보를 보여주는 간단한 서비스라 딱히 장애날부분이 없을텐데.. 뭐지? 버근가..?" 라는 생각을 하며 월요일 확인해보니 

있어야할 디비 데이터가 없습니다..

(물론 백업이 있기에 간단히 복구 할수 있지만..)

 

"응? 왜 갑작이 데이터가 날아갔지?" 라는 생각을 하며 db 접속해보니 이상한 db가 하나 추가 된것을 확인했습니다.

허허허..털렸네요...

(물론 서비스중이 아니기에 비트코인을 보내고 복구할필요도 없지만 말입니다.. ㅎㅎ)

 

사실 제 시스템은 털기 아주 간단하긴 했습니다..

개인적으로 테스트로만 사용중이기 때문에 아주아주 취약한걸 알고도 보안을 전혀 신경쓰지 않았습니다.

(당연히 해야되는거지만.. 테스트용으로 구성한거라..^^;;;)

 

그래도 이렇게 들어와서 데이터를 날린다면 귀찮으니 조금의 보안을 위해 조치를 해보며

글을 남깁니다.

 

 

1. 먼저, 현재 라즈베리파이는, 공유기의 포트포워딩을 통해 접근할 수 있도록 열어 놓았고, 마찬가지로 DB 포트도 열려있습니다, IP 제한도 없고, 포트도 27017로 동일하게 열어 놓았었습니다.

-> DB 접근은 어플리케이션 IP만 및 제 개발 PC 만 열어놓아야 하는것이 맞겠지만, 이 부분은 여전히 편의성을 위해 설정하지 않을 예정입니다.

-> 포트를 27017을 그대로 사용하지 않고 임의의 포트로 수정하였습니다(무작위 아이피로 몽고 공식 포트로 찔려보는것이였을 꺼라 생각합니다.)

 

2. 계정은 생성해뒀지만, 최근 테스트를 위해 "authorization: disabled" 상태로 두었었습니다. 이러니 간단히 털수 있었겠죠

-> authorization: enabled 로 변경 하였습니다. 그리고 기존 계정은 삭제하고 새로 생성했습니다.

 

더더욱 많은 보안들을 적용할 수 있겠지만 아주 간단한 조치만으로도

왠만한 해킹들에 대해서는 막힐것이라 기대합니다

(또 털리면 다시 글을 남기게 되겠지요)

 

3. 서비스중 하나는 동적으로 데이터가 쌓이지 않아 백업이 다 되어 있지만, 하나의 서비스는 계속해서 크롤링하여 데이터를 쌓는데 백업이 되어있지 않았습니다.

(물론 실서비스가 아니기에 신경을 쓰지 않았지만요...)

-> 추후 데이터 백업 관련하여 적용해야겠습니다.

 

4. 이제 변경된 계정 정보 및 포트들을 적용해야하는데, spring config server를 사용하고 있기 때문에 간단히 git repo의 설정 정보를 변경하는것으로 간단히 적용되었습니다.

 

 

요약

1. 공식 포트를 그대로 사용하지 말자!(SSH 포트인 22라던지.. 디비포트 1521이나 27017이라던지)

2. 계정 보안을 켜두고 쓰자

3. 데이터는 늘 백업하자

 

 

'DB' 카테고리의 다른 글

[DB] 기초부터다시, ACID, CAP  (0) 2020.09.14
GraphQL 끄적끄적  (0) 2020.08.20
기초부터다시, 조인  (0) 2020.08.18
[MyBatis] MyBatis 문법 파서  (0) 2019.05.29
DB 스키마를 관리하자  (0) 2018.12.20

댓글()

spring boot log level 변경(actuator)

JAVA/Spring|2019. 12. 19. 19:50

로그레벨 동적 반영을 위하여

Controller를 하나 만들어서 처리할까 하다 이미 구현된 기능이 있을지 해서 검색해보니

이기 해당 기능이 actuator를 이용하여 처리가 가능하도록 되어있었습니다.

 

먼저 actuator를 사용하기 위해 pom.xml 에 추가합니다.(메이븐 기준으로)

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

 

설정 없이는 /actuator 로 확인할수 있는것들이 없지만 'management.endpoints.web.exposure.include' 에 항목들을 추가하여 추가적인 기능들을 사용할 수 있습니다.

management.endpoints.web.exposure.include=loggers

#management.endpoints.web.exposure.include=httptrace,loggers,health,info,metrics

 

logger 설정 및 확인을 위해 필요한 내용은 loggers입니다.

 

위와같이 설정 후 기동하게되면

'/actuator/loggers' 를 통해 모든 로거들의 로그레벨들을 확인할 수 있습니다.

 

 

'/actuator/loggers/로거명' 을 GET으로 요청하면 해당 로거만 나타나게 됩니다.

 

이제 목표인 로그레벨 동적 변경을 위해서는

'/actuator/loggers/로거명' 에 POST로 설정할 값을 보내주면 됩니다.

{"configuredLevel":null,"effectiveLevel":"INFO"} 를

{"configuredLevel":"ERROR","effectiveLevel":"ERROR"} 로 변경하고자 하면

 

헤더는 컨텐츠 타입을 application/json에 body에 {"configuredLevel":"ERROR","effectiveLevel":"ERROR"} 을 넣어 요청하도록 하면 됩니다.

 

 

 

'JAVA > Spring' 카테고리의 다른 글

[MSA] sidecar 패턴  (0) 2020.01.13
[SpringConfig] Properties 암호화  (0) 2019.12.24
reactor Schedulers  (0) 2019.12.16
스프링 부트 2.2 릴리즈노트  (0) 2019.11.01
[Spring] zuul 사용시 Eureka client로 분배가 안되는경우  (0) 2019.08.16

댓글()

reactor Schedulers

JAVA/Spring|2019. 12. 16. 20:47

Mono 혹은 Flux를 다룰때 map 혹은 subscribe 동작들을
subscribeOn()이나 publishOn()을 통해 다른 스레드에서 실행될 수 있도록 위임할수 있는데
인자는 Scheduler를 받습니다.


Spring WebFlux에서 Controller 스레드에서는 blocking 작업을 할수 없도록 되어있기에
필요한 경우에 subscribeOn() 를 사용하여 blocking 작업을 다른 스레드에서 사용할 수 있는데
Scheduler 종류마다 blocking 작업이 가능한 Scheduler가 있고 아닌 Scheduler 가 있습니다.
(non-blocking 스케줄은 블럭킹 작업이 불가능합니다.)





새로 신규로 생성하여 넘길수 있겠지만 Schedulers가 기본적으로 몇가지를 지원합니다.

  • parrallel
    • optimized for fast non-blocking executions
    • 속도 최적, non-blocking
  • single
    • optimized for low-latency one-off executions
    • 스레드 하나를 공유함, non-blocking
  • elastic
    • optimized for longer executions, alternative for blocking tasks where the number of active tasks can grow indefinitely
    • 긴작업에 최적, non-blocking 아님, blocking 작업 가능 스레드, 필요시 무한히 늘어남
  • boundedElastic
    • optimized for longer executions, alternative for blocking tasks where the number of active tasks is capped
    • 긴작업에 최적, non-blocking 아님, blocking 작업 가능 스레드, 정해진 사이즈
  • immediate
    • to run a task on the caller Thread
    • 콜러 스레드에서 실행
  • fromExecutorService
    • 기존 java.util.concurrent.Executors 를 활용

댓글()

JEP 218: Generics over Primitive Types

JAVA|2019. 12. 10. 19:23

이전에

List list = new ArrayList<>();

list.add(3);

int val = list.get(0);

에 대한 질문을 본적이 있습니다.

현재(지금까지 접했던)까지의 Java는 Generic에 primitive인 가 아닌 로 적어야 맞는것

그리고 list.add(3); 에서 auto-boxing 에 대해 언급했었습니다.

그리고 int val = list.get(0); 에서는 un-boxing이 일어나게 되죠

즉, 불필요한 객체가 생성되고 사라집니다.

검색을 하다보니 이부분을 "어쩔수 없다"가 아닌 해결해보려는 프로젝트가 있었습니다.

 

Valhalla 프로젝트

Valhalla 프로젝트에서는 크게 2가지 내용이 있었습니다.(https://openjdk.java.net/projects/valhalla/)

  • Value Types
  • Generic Spcialization(JEP 218)

그중 Generic Spcialization(JEP 218) 가 Generics over Primitive Types 에 다루고 있는 항목이였습니다.
https://openjdk.java.net/jeps/218

 

JEP 218: Generics over Primitive Types

JEP 218: Generics over Primitive Types Summary Extend generic types to support the specialization of generic classes and interfaces over primitive types. Goals Generic type arguments are constrained to extend Object, meaning that they are not compatible wi

openjdk.java.net

JEP(JDK Enhancement Proposal) 내용이기 때문에 언제 이루어질지 알수 없지만

하나씩 하나씩 추가되고 개선될때마다, 코틀린이나 스칼라가 아닌 자바

그 자체로 간편하고 더더욱 효율적인 언어가 될것을 기대한다.

 

 

'JAVA' 카테고리의 다른 글

SortedQueue...  (0) 2020.07.02
java.util.function 인터페이스  (0) 2019.12.30
[CompletableFuture][#3] 메소드 정리-1  (0) 2019.09.01
[Quartz] Trigger  (0) 2019.07.10
[CompletableFuture][#2] staticMethod  (0) 2019.07.09

댓글()

Zookeeper

Server|2019. 12. 9. 19:04

Zookeeper는 Zookeeper 단독으로도 사용되지만, 하둡이나 카프카 등 여러 다른 시스템들과 함께 활용되고 있지만

저의 경우에는 Zookeeper 자체에서 어떤 기능들을 제공하는지 조차 모르고 사용하기도 했습니다.

그래서 조금씩 파악중이며 조금씩 수정해갈 예정입니다.

Zookeeper는 기본적으로

  • 메타 저장소

  • 데이터 변화 감시를 위한 Watcher

  • 데이터 snyc 혹은 분산 어플리케이션을 위한 lock 제공

  • 간단한 설정을 통한 클러스터 지원
    와 같은 기능들을 제공하며(이것 말고도 많겠지만)

    참고로 메타는 각 노드에 저장되며, 노드는 트리구조로 되어있고, 트리를 쉽게 접근할수 있도록 파일시스템과 같이 접근할 수 있습니다(/data/node1/info).

    그리고 노드도 여러가지 종류들을 제공합니다.

    • Ephemeral Nodes
      • 세션동안 유지되는 노드, 연결이 끊어지면 삭제
    • Sequence Nodes
      • 고유명을 위한 노드
    • Container Nodes
      • 락을 위한 노드(3.5.3에 추가됬다고 하는데 사용을 아직 못해봤네요)
    • TTL Nodes
      • 마찬가지로 3.5.3에 추가

분산 어플리케이션들은 보통 Zookeeper의 클라이언트가 되고, Connection을 지속적으로 유지하고 있습니다.

Zookeeper에서 데이터 변화 감지를 위해 Watcher를 제공하기 때문에 polling을 하며 감시 할 필요 없이
동작만 CallBack 코드만 작성해 두면 되기에 훨씬 간결해 질 수 있습니다.

Watcher의 경우 노드 하나 변화에 Wacher를 설정할 수 있고, 노드 하위에 변화에도 대해 설정 할 수 도 있습니다.

  • 데이터 변화에 대한 Watcher
    • get -w /data
  • 데이터 하위 생성에 대한 Watcher
    • ls -w /data

Zookeeper를 활용하여 할수 있는 것들은 많겠지만
일단 간단하게 구현 해본 부분은 "분산 어플리케이션에서 서로의 노드 추가 삭제 감지 에 따른 동작"
상위 Node를 하나 생성하고, 어플리케이션마다 하위에 ephemeral + sequence Node를 생성하고
서로 상위 Node를 Watcher 하게 하면
간단히 분산 어플리케이션에서 어플리케이션 변화를 감지 할 수 있고
Watcher 코드에 대응되는 동작을 넣는것으로 간단히 "분산 어플리케이션 상황에서 각 어플리케이션 감지 및 동작" 을 처리 할 수 있습니다.

해당 글은 Zookeeper를 살펴보거나 사용할 때 마다 기록을 위해 업데이트 할 예정입니다.

'Server' 카테고리의 다른 글

[Oracle] auto commit error  (0) 2020.07.29
[Kafka] 토픽 삭제 후, 브로커 기동안됨  (0) 2020.06.24
Nginx Service 로 등록  (0) 2014.08.13
Jconsole (톰캣 모니터링,자바 모니터링)  (0) 2014.08.12
Varnish 설치 Centos, FreeBSD  (0) 2013.10.30

댓글()

스프링 부트 2.2 릴리즈노트

JAVA/Spring|2019. 11. 1. 18:20

한 달 동안 잠시 해외를 다녀온 사이 Spring Boot 2.2가 릴리즈 되었습니다.
지금까지 버전업 되면서 변경 사항들을 모두 파악하지는 못했지만
계속 사용하게될 SpringBoot이기 때문에 2.1x에서 2.2x로 올라가며 변경돼 사항을 파악하고자
릴리즈 노트를 번역 및 개인적으로 궁금한 사항을 파악해보았습니다.

릴리즈 정보 출처

https://spring.io/blog/2019/10/16/spring-boot-2-2-0
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.2-Release-Notes


스프링 관련 프로젝트 업데이트

  • Spring AMQP 2.2
  • Spring Batch 4.2
  • Spring Data Moore
  • Spring Framework 5.2
  • Spring HATEOAS 1.0
  • Spring Integration 5.2
  • Spring Kafka 2.3
  • Spring Security 5.2
  • Spring Session Corn

서드 파티 라이브러리 업데이트

  • Elasticsearch 6.7
  • Flyway 6.0
  • Jackson 2.10
  • JUnit 5.5
  • Micrometer 1.3
  • Reactor Dysprosium
  • Solr 8.0

성능 개선

SpringBoot2.1보다 2.2에서는 더 빠른 시작과 더 적은 메모리 사용량을 보여줄 것이며 특히 타이트한 메모리 환경에서 유용할 것입니다.

초기화 지연(Lazy initialization)

spring.main.lazy-initialization 속성을 통해 전역으로 lazy init을 활성화시킬 수 있습니다.
초기화를 늦춤에 따라 아래의 추가적인 비용들이 발생합니다.

Java13 지원

Spring 5.2가 Java 13을 지원함에 따라 Spring Boot2.2도 Java 13을 지원하며, Java11과 Java8 또한 지원합니다.

@ConfigurationProperties 생성자 바인딩 지원

설정 properties는 이제 생성자 바인딩을 지원하기 때문에 클래스의 불변을 지원합니다.
@ConfigurationProperties를 붙이거나, @ConstructorBinding를 붙이면 생성자 바인딩이 활성화되며, @DefaultValue와 @DateTimeFormat 이 생성자 바인딩으로 동작합니다.

RSocket 지원

RSocket에 대한 자동 설정을 지원합니다. spring-boot-starter-rsocket

 

수정 중이며 잘못된 내용이 있으면 의견 부탁드립니다.

감사합니다.

댓글()

[Kotlin] default argument, named argument

Kotlin|2019. 9. 18. 20:10

코틀린이 편리한 부분이 많다는것들은 많이 봤지만

("var ${var}" 도 그렇고.. data class도 그렇고 null check도 그렇고 너무 많네요..;;)

 

몰랐던 기능이 있어 기록을 남깁니다.

 

먼저 "default argument"

 

자바에서 보통 인자가 없을때 그리고 인자가 있을때 처리를 위해

메소드 오버로딩으로 처리하곤 합니다

 

이코드가 결국에는 default 값 처리를 위한 건데

결국 arg가 없는 메소드를 열어봐야 기본값을 알 수 있습니다.

public void hello(){
	hello("kim");
}

public void hello(String name){
	System.out.println("Hello " + name);
}


/////////아니면 아래처럼 null로 넘기고 null이면 기본값 처리하는 방법이..

public void hello(){
	hello(null);
}

public void hello(String name){
	String localName = name;
	if(localName==null){
		localName="kim";
	}
	System.out.println("Hello " + localName);
}

 

그런데 코틀린에서는 아래와 같이 코드를 작성해서 default argument를 설정할 수 있습니다.

fun hello(name: String="kim")=println("hello ${name}")

훨씬 간결해집니다.

 

그럼 인자가 많아지거나 다양해지면 어떻게 하나?

(몇개는 입력을 받고 몇개는 default로 처리하고 싶을때... )

 

자바로 작성하면 null체크를 덕지덕지 처리를 해주기도하고

overload 메소드를 거의 종류별로 만들어야 하는 경우도 생기기 때문에

args가 늘어나는것 대신 보통 input용 클래스를 빌더패턴으로 만들던 그냥 data 클래스로 만들던 만들어서 코드를 처리하기도 합니다.

 


	public void order() {
		order(null, -1);
	}

	public void order(int cnt) {
		order(null, cnt);
	}

	public void order(String menuName) {
		order(menuName, -1);
	}

	public void order(String menuName, int cnt) {
		String localName = menuName;
		if (localName == null) {
			localName = "대표메뉴";//default Menu
		}
		int localCnt = cnt;
		if (localCnt == -1) {
			localCnt = 1;// default Cnt
		}
		System.out.println(menuName + " order " + cnt);
	}

 

코틀린에서는 "named argument"를 써서 쉽게 처리할 수 있습니다.

 

fun order(menuName: String="대표메뉴", cnt: Int=1)=println("${menuName} order ${cnt}")

여기까지는 위에 default argument와 동일합니다.

여기서 중요한건 사용할때 기존 order(null,10) 형태로 호출하는것이 아니라

아래와 같이 인자를 줄때 변수을 명시해서 넘길수 있습니다.

		order("피자", 5)//결과적으로 "피자 order 5", 모두 채운 기존 형태
		order(3)//에러
		order("피자")//결과적으로 "피자 order 1"
		order(menuName = "피자")//결과적으로 "피자 order 1"
		order(cnt = 3)//결과적으로 "대표메뉴 order 3"
		order(menuName = "피자", cnt = 5)//결과적으로 "피자 order 5"
        order(cnt = 5, menuName = "피자")//결과적으로 "피자 order 5", 순서 상관없이 잘 동작합니다
		

 

named argument 덕분에 첫번째 인자가 어떤 변수인지 두번째 인자가 어떤 arg인지

메소드 선언을 보지 않아도 호출하는 쪽에서 변수명을 명시하면 혼동을 덜할수 있고

arg순서가 바뀌거나(물론 유지보수를 위해 메소드 arg를 막 변경하는 사람은 없겠지만) arg가 늘어나는 경우에도

대응하기 좋을것으로 보입니다.

 

 

 

댓글()

[Kotlin] 코틀린에 primitive가 없다고? 느리지 않을까?

Kotlin|2019. 9. 10. 19:47

자바에는 primitive 타입과 Object 타입이 동시에 있는 것들이 있다는 것은

자바 개발자라면 대부분 다들 알고 있을 겁니다.

(int와 Integer , long와 Long, 등등....)

 

primitive 타입과 Object 타입이 각각 존재하는 것은 

여러 가지 이유가 있지만, 제가 생각하는 가장 큰 이유는

연산을 할 때마다 새로운 객체를 만들기 위해 메모리 할당을 한다면 성능상 문제가 생길 수 있기 때문에

(보통 Object + Object는 새로운 Object를 생성... 숫자 연산마다 메모리 할당이 생긴 하다.. 문제가 되겠죠)

출처 : https://www.scientecheasy.com/2018/06/memory-allocation-primitive-nonprimitive.html

primitive type을 두어 primitive는 heap에 할당하지 않고 스택에 value를 바로 value를 저장하여 성능 향상한 것으로 알고 있습니다.

 

primitive를 통해 성능 향상한 것은 좋지만, java Collection을 통해 int를 담거나 제네릭으로 타입을 처리하거나

할 때 primitive로는 처리가 불가능하기 때문에

primitive를 wrapping 타입(Integer)으로 변경해야 하는 경우가 필요하곤 합니다.

 

물론, java에서 자동으로 primitive에서 wrapping 타입 변환(auto-boxing) wrapping에서 primitive(auto-un-boxing)을 해주기도 하지만, 편리할 뿐 boxing 때마다 object가 생기고 사라지기 때문에 그리 성능상 좋지는 않고 불편하기도 합니다.

(NPE 문제.. 타입 처리 문제...)

 

불편하기도 하지만 성능 때문이라도 계속 primitive 타입이 존재하죠..

그래서, 많은 연산 시에는 wrapping 타입 대신 primitive 타입을 사용하라곤 합니다.

 

int[] values = {...};

int sum=0;
for(val : values){
	sum+=val;
}


Integer sum=0;//이렇게 하지 말라곤 하죠
for(val : values){
	sum+=val;//이렇게 하지 말라곤 하죠
}

 

 

그런데!

코틀린은 이 불편한 primitive가 없다고 합니다.

(실제로 코틀린은 int 대신 Int, double 대신 Double)

없어져서 좋을 수 있지만, "그럼 코틀린은 wrapping 타입만 사용한다는 걸까? 그럼 느리지 않을까?"

라는 의문이 생겼습니다.

 

그럼 위에서 언급한 연산 때마다 객체가 생기고 사라지고를 반복해서 문제가 생기지 않을까요?

 

그래서 테스트해봤습니다.

 

테스트 방법은

  • 1. 테스트 코드 작성
  • 2. class 파일 생성
  • 3. 디컴파일러로 class 파일 확인

을 통해 어떻게 class 파일이 생성되는지 확인하려고 합니다.

 

 

1. 자바

먼저, 자바로 primitive일 때

 

	int number_1 = 100;
		number_1 += 10;

	int number_2 = 200;
		number_2 += 10;

	int sum = number_1 + number_2;
		System.out.println(String.format("sum : %d", sum));

 

하단은 디컴파일러를 통해 본 자바 primitive 코드

 

거의 차이가 없습니다. 다만 마지막 라인에 String.format()에

마지막 arg는 Object []이기 때문에 Integer.valueOf()로 오토 박싱 한 부분이 보입니다.

 

지금까지 객체는 마지막 한 번만 객체 생성이 되겠네요

(물론 정확하게는 Integer.valueOf()가 내부적으로 범위 값만큼은 객체를 캐싱을 하고 있기 때문에 객체를 만들지 않겠지만요..)

 

두 번째로, 박싱 타입인 Integer로 위 코드를 사용하면 어떻게 코드가 생성되는가?

	Integer number_1 = 100;
		number_1 += 10;

	Integer number_2 = 200;
		number_2 += 10;

	Integer sum = number_1 + number_2;
		System.out.println(String.format("sum : %d", sum));

 

하단은 디컴파일러를 통해 본 자바 Integer 코드

 

 

 

100이라고 적은 int는 number_1이 Integer 타입이기 때문에 Integer.valueOf()로 오토 박싱 처리되었고

number_1 +=10 은 number_1이 Integer 타입이기 때문에 내부 primitive를 가져오는. intValue()를 사용해서 int인 10과 더하고

다시 박싱 하여 number_1에 assign 하는 식으로 동작하는 것을 볼 수 있습니다.

 

앞서 말한 것처럼 거의 연산 때마다 객체가 새로 생성되는 것을 볼 수 있습니다.

 

 

2. 코틀린

 

궁금해하던 코틀린입니다.

타입을 명시하지 않고 해 봤습니다.

(:Int로 명시해도 디컴파일 결과는 같았습니다.)

	var number_1 = 100;
		number_1 += 10;


	var number_2 = 200;
		number_2 += 10;

	var sum = number_1 + number_2;
		println("sum : ${sum}")

 

하단은 디컴파일러를 통해 본 코틀린 코드

 

 

디컴파일 했더니 박싱 타입인 Integer를 사용하지 않고 primitive 인 int로 생성되는 것을 볼 수 있었습니다.

Integer가 아닌 int로 변환한 걸 봐서는 우려했던 부분에 성능 문제는 발생하지 않겠네요

다만, println("sum : ${sum}")에 문자열 조합을

+연산을 통해 처리하고 부분이 조금 마음에 걸리네요(물론 variable이 하나라 +를 쓴 건지 나중에 확인해봐야겠네요)

 

 

마지막으로 하나 더 테스트해봤습니다.

:Int를 primitive로 처리하고 있는 건 알겠는데

"그럼 Collection에서는 primitive int로 어떻게 처리하려나?"였습니다.

 

var list = arrayListOf<Int>();

(1..10).forEach { n -> list.add(n) }

list.forEach { n -> println(n) }

 

하단은 디컴파일러를 통해 본 코틀린 코드, 실제 코드는 3줄이나, 코드는 정말 길게 만들어지네요..

 

....

 

여기서 사실 살펴볼 쪽은 색칠해둔 부분인데 너무 작아 보이지 않으실 테니

적자면

list.add(Integer.valueOf(n))

으로 처리를 하고 있습니다.

결국에는 ArrayList를 사용하기 위해 자바와 동일하게 오토 박싱을 하고 있긴 하네요

 

 

 

결론

코틀린에는 primitiveType은 없지만, 바이트코드로 변환 시 가능한 한 primitiveType으로 바꿔주어

연산 시 성능 문제는 발생하지 않을 것으로 보이며

Collection은 마찬가지로 autoBoxing 처리를 하고 있다.

 

 

나중에 자바에서는 String append시 StringBuilder나 Buffer를 사용하도록 하는데

코틀린에서는 어떻게 처리하고 있나 봐야겠습니다.

 

'Kotlin' 카테고리의 다른 글

split과 동시에 assign  (0) 2021.11.29
코틀린 upgrade 1.3.7 to 1.5.0  (0) 2021.05.28
[Kotlin] default argument, named argument  (0) 2019.09.18
[Kotlin] data class  (0) 2019.09.09
[Spring][Kotlin] 필드에 @Autowired 어떻게 사용하나?  (0) 2019.09.06

댓글()