About Binary Number

이미지
이번 글에서는 기초로 돌아가는 시간을 가진다. 컴퓨터에서 정수와 실수를 어떻게 다루고 있는지에 대해서 정리하려고 한다. 우리는 일상생활에서는 10진법을 사용한다. 아무래도 손가락이 10개라서 이지 않을까?  하지만 컴퓨터에서는 2진법을 사용한다. 컴퓨터는 10진법을 이해하지 못한다.  컴퓨터가 사용하는 2진법 컴퓨터는 손가락이 2개만 있다.  컴퓨터는 전압을 사용하여 동작한다. data 가 있을 경우 전압을 올리고 없을 경우 내린다. on / off 로 부를 수 있는데 이러한 과정을 계속해서 반복한다. 전압을 올린 곳은 1 로 표현할 수 있고, 전압이 없을 경우 0으로 표현한다. 이러한 data 를 연결할 경우 101101 과 같은 data 가 된다. 이러한 data 0 또는 1 을 bit 라고 부른다. 1bit 는 0 또는 1 두가지 경우를 나타낼 수 있다. 1bit = 0, 1 = pow(2, 1) = 0 ~ 1 2bit = 00, 01, 10, 11 = pow(2,2) = 0 ~ 3 4bit = 0000, 0001, 0010, ... 1111 = pow(2,4) = 0 ~ 15 8bit = 0000 0000, .... 1111 1111 = pow(2,8) = 0 ~ 255 bit 가 8개 8bits 는 1 byte 가 된다. 8bits 의 절반인 4bit 를 nibble 이라고 부른다. 컴퓨터가 저장하는 최소단위가 byte 이다. 8 bits = 2 nibble = 1 byte 이다. nibble 은 4bits 이다. nibble  단위가 16진수의 단위가 된다.  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, a, b, c, d, e, f 1111 1111 은 10진수로 15 15 이고 16진수로 표현하자면 f f 가 된다. 0xFF 가 된다. 0xFF 는 1 byte 가 된다. 정수 2진 표현 Kotlin 을 기준으로 Int 는 4 bytes 로 32 bits 이다. 양의 정수 5028 을 2진...

Time Business Logic Testing on Spring (Kotlin, Java)

이미지
올해에 너무 글쓰는 것을 소홀히 했던것을 반성하며 남은 한 달 동안 글을 몇 개라도 조금 써보려고한다! Java, Kotlin 기반 Spring 프레임워크 환경에서 개발을 하다보면 시간과 관련된 로직이 필요할 수 있다. 이 때 어떻게 해결하면 좋을 지 테스트 코드는 어떻게 구성하면 좋을지 정리하려고 한다. 예를 들어, 특정 기간동안만 액션이 가능한 요구사항이 있다고 가정하자. 해당 기간이 시작하기전에 액션을 진행하지 못하도록 막아야 되고, 기간인 경우 가능하도록 그리고 기간이 끝났을 때 더이상 액션이 불가능하도록 막아야 한다. 이 예제를 바탕으로 간단한 샘플 코드를 정리해보았다. - Kotlin - Spring Boot 2.7.5 - Junit 5 우선 아래와 같이 zoneId 를 인자로 받는 now 함수를 작성하였다. CHANGEABLE_CLOKC 이 null 이 아닐경우 해당 Clock 을 기준으로 LocalDateTime 인스턴스를 생성한다. 그리고 now 를 테스트하기 위한 코드. CHANGEABLE_CLOCK 이 null 인 경우와 null 이 아닌 경우 두 가지 테스트 케이스이다. null 인경우에는 zoneId 에 따라서 인스턴스를 생성하기 때문에 빈 인자인 경우 UTC 기준, Kst ZoneId 제공시 kst 시간 인스턴스를 생성하여 9시간 차이를 확인하는 코드이다. 두번 째는 Clock 을 2025 년 1월 1일로 설정하여 now 함수 호출 시 CHANGEABLE_CLOCK 기준으로 인스턴스를 생성하게 되어있다. 자 그렇다면 기간과 관련된 로직과 해당 로직을 테스트하는 코드를 작성해보자. 아래와 같이 property 에서 기간을 주입받는 Service 를 test code 를 작성해보자. ReflectionTestUtils 를 통해서 Mocking 하는 service 에 기간을 주입한다. 그리고 CHANGEABLE_CLOCK 을 통해서 now() 함수가 기간에 속할 때와 아닐 때로 지정하여서 올바른 값을 반환하는지 검증한다. 또 다른 방법중 하...

Multiple Java In My Mac

이미지
 Java 언어를 통해서 개발을 하다보면 프로젝트마다 Java Version 이 달라서 스위칭하는 데에 꽤나 번거롭다. 조금이나마 간단하게 해결하기 위해서 이 글을 정리한다. 우선 나의 로컬에는 아래와 같이 3가지 version 의 JDK 가 공존한다. - Zulu 13 - Amazon Corretto 11 - Amazon Corretto 8 현재 설정된 JAVA_HOME 아래와 같이 지정한 alias 를 통해서 JAVA_HOME 을 편하게 변경해보자. 먼저 .zshrc 또는 .bash_profile 을아래와 같이 작성한다. version 에 따른 JAVA HOME 변수를 할당하고 각각의 alias 를 통해서 JAVA_HOME 을 switch 시킬 수 있도록 한다. 이외에도 jenv 를 통해서 관리할 수 있다. https://www.jenv.be/

String is Immutable In Java

이미지
개요  Java 에서 String 을 어떻게 다루고 있는지 정리해보겠다. Java 에서 String 은 Immutable 로 즉 불변이다. Java 의 아버지 제임스 고슬링은 "I would use an immutable whenever i can." 이라고도 말했다. 어떠한 이유에서 이러한 말을 했는지 알아보자. Immutable 먼저 Immutable 이란 무엇일까? 불변이란 생성 후에 내부 상태를 변경할 수 없다는 것을 나타낸다. 다시 말해, 생성 후 객체를 변수에 할당하고 나면 해당 객체 참조를 변경하거나 내부 상태를 변경할 수 없고 다시 생성해야지 해당 참조를 변경할 수 있다. Why String is Immutable? 바로 caching, security, synchronization and performance 이다. 차례대로 확인해보자. String pool String pool 은 JVM 에 의해서 String 들이 저장되는 특수한 메모리 영역이다. literals 로 String 변수를 할당하게 되면 다른 변수일지라도 같은 내용일 경우 String pool 에 있는 같은 객체를 참조하게 된다. 이를 통해서 heap 영역을 절약할 수 있고 재사용성을 높인다. s1 과 s2 는 literals 로 String 을 생성했기에 s1 변수가 할당 될 때 String pool 에 "hello world" 가 생성되고 s2 변수가 할당될 때 기존에 s1 이 가르키고 있는 String pool 의 "hello world" 를 참조하게 된다. 반대로 new String() 을 통해서 생성한 String 은 같은 참조를 가르키지 않는다. 항상 새로운 객체를 생성하게 된다. Security Java Application 에서 String 은 username, password, connection URLs, network connections, etc. 와 같이 민감한 자료를 저장하는데 사용된다. 따라서 보안...

I need to know a little Garbage Collection

이미지
개요  프로그래밍 언어에는 2가지 언어가 있다. Managed 언어와 Unmanaged 언어로 구분된다. 이 둘의 가장 큰 차이점은 개발자가 직접 메모리를 할당하고 해제하는 관리 여부로 결정된다.  대표적인 Unmanaged 언어로 C, C++ 이 있고, Managed 언어로는 Java, Python, Go, C# 등이 있다. 이번글에서는 알아서 memory 를 관리해주는 Garbage Collection 에 대해서 정리해보려고한다. 언어마다 Garbage Collection 알고리즘이나 기법이 다르다. 이 글에서 다루고자 하는 언어는 Java 이고 JVM 이다. What? Heap 영역에서 어떤 object 가 사용중인지 아닌지 확인하고 사용하지 않는 object 는 삭제한다. 사용중인 object 는 referenced object 로 program 에서 해당 object 에 대한 pointer 를 유지하고 있는 것을 의미한다. 사용하지 않는 object 는 unreferenced object 로 더 이상 program 에서 pointer 를 유지하고 있지 않는 것을 의미한다. 따라서 unreferenced object 의 memory 를 회수할 수 있다. C 나 C++ 은 수동으로 memory 를 allocate 하고 deallocate 한다. Java 에서는 Garbage Collector 에 의해서 자동으로 관리된다.  첫 번째 : Marking Garbage Collector 가 memory 의 사용여부를 확인하는 작업이다. referenced objects 들은 파란색이다. Unreferenced objects 는 주황색이다. 모든 objects 는 Marking 단계에서 scan 작업을 거친다. 만약 전체 시스템의 모든 objects 를 scan 해야 한다면, 이 작업은 시간이 많이 드는 작업이다. 두 번째 - 1 : Normal Deletion Normal deletion 은 unreferenced objects 지우지...

I need to know a little JVM

이미지
개요 현재 개발자 채용시장에 있어서 Java 가 가장 영향력있는 언어이지 않을까 생각한다. Java 가 영향력이 큰 이유는 아마도 ecosystem 덕분이지 않을까 생각이 든다. 최근에 여러 모던 언어들이 등장하고 있지만, 여전히 Java 에 입지는 굉장히 강력하다. 물론 Kotlin 이라는 언어가 등장하면서 판도의 흐름이 보이고 있다. 둘의 공통점은 JVM 기반 언어라는 점이다. (물론 Kotlin/JS 는 다른이야기 이지만) 이외에도 Scala, Clojure, Groovy 등등 JVM 기반 언어들이 많다. 이번글에서는 JVM 을 high-level 구조를 정리해보려고 한다. 해당 구조는 Java 8 을 기준으로 정리를 했다. 현재 LTS 로 Java 17 까지 출시가 되었으며 변경사항이 있는 것을 참고해야 한다. JVM 구조 ClassLoader Subsystem JVM 언어의 철학 중 하나가 Write Once Run Anywhere 이다. compile 시 하드웨어가 바로 이해할 수 있는 low-level 로 번역이 되는 것이 아닌 JVM 이 이해할 수 있는 byte code 로 변환된다. 바로 class 파일 포맷이다. ClassLoader 의 역할이 바로 compile 된 class 파일들을 runtime 에 동적으로 load 하는 역할을 한다. ClassLoader 로 인해서 runtime system 은 machine 의 file 및 filesystem 을 알 필요가 없다. 모든 class 파일은 한번에 load 되는 것이 아니다. 필요한 시기에 필요한 class 파일을 요청하며 이에따라 요청받은 ClassLoader 가 역할을 한다. 또한 ClassLoader 는 하나가 아니다. 요청한 class path 나 type 에 따라 동적으로 ClassLoader 가 선택된다. ClassLoader 는 3가지 종류가 있다. - Bootstrap ClassLoader : java class 가 아닌 c/c++ 로 이루어져있다. JDK interna...

Statement and PreparedStatement

이미지
이번글에서는 JDBC API Statement 와 PreparedStatement 의 차이점에 대해서 정리하려고한다. Java Database Connectivity API 는 Java 를 사용하여 data access 를 할 수 있도록 제공해준다. RDBMS 뿐만 아니라 spreadsheets 와 flat files 도 가능하다. JDBC API 는 2개의 패키지로 구성된다. - java.sql - javax.sql Statement String-based query 를 실행시킨다. parameter 대신 static SQL 을 처리하기 좋다. runtime 에 오직 한 번만 실행시킬 DDL 을 사용하기 적합하다. Binary Data Read / Write 작업에 사용이 불가능하다. Binary Protocol 이 사용되지 않는다. SQL Injection 에 취약하다. PreparedStatement parameterized query 를 기반으로 한다. runtime 에 parameter 를 다루고 여러번 수행되는 어떤 종류의 Query 도 처리하기 좋다. Dynamic query 를 처리하기 좋다. Binary Data Read / Write 작업이 가능하다. Binary Protocol 사용이 가능하다. 둘의 가장 큰 차이점은 precompiled 에 따른 성능과 보안 측면에서 SQL injection 방지이다. 참조 https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/ https://www.baeldung.com/java-statement-preparedstatement https://www.geeksforgeeks.org/difference-between-statement-and-preparedstatement/ https://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html#:~:text=As%20a%20result%2C%20the%20...