String 에 대하여

영주·2024년 11월 3일
0

CS

목록 보기
1/3

⭐ TODO

  • StringBuilder 를 사용하면 어떤 이점이 있는거죠?
    • String, StringBuilder, StringBuffer
  • UTF 가 뭐에요?
    • 이모지, 한글은 몇 byte 인가요?
  • 대문자와 소문자 구분은 중요한가요? 어떻게 생각하세요?
    • 키워드 : mysql collation

String 에 대한 고민..

❓String

✅ 특징

  • JAVA의 기본 자료형에 속하지 않는 class 이다.
  • Immutable (불변성)
    : 한 번 생성한 문자열 객체는 수정할 수 없다! → thread-safe

String str = "Hello" // (1)문자열 리터럴
str += "world!" // (2)

String str1 = new String("Hello"); // (1)new
str1 += " world"; // (2)

(2)번 연산 수행하면서 새롭게 (2)Hello World! 를 위한 메모리를 할당하고, (1)로 초기화한 str 객체는 GC의 대상이 된다. → 반복되면 성능에 안좋음..

 

✅ 메모리 할당 (1)문자열 리터럴 : String Constant Pool 사용

String str1 = "Hello";
String str2 = "Hello";
  1. 문자열 리터럴을 통해서 str1을 생성하면 String Constant Pool에 저장
  2. str2의 내용이 str1과 동일하므로, 새로 공간을 만들어 할당하지 않고 String Constant Pool 에서 str1과 같은 주소를 가리킨다.
  • 동일한 문자열 리터럴 사용 시, 새로운 메모리를 할당하지 않으므로 메모리 낭비가 덜하다.
  • == 연산자로 정확한 비교 가능(메모리 주소 비교)
    (But, 리터럴 방식이든 new 방식이든 상관없이, 문자열 비교는 항상 equals() 하는 것이 좋다.)
System.out.println(str1 == str2);  // true

 

✅ 메모리 할당 (2)new 키워드 사용 : Heap 영역

String str3 = new String("Hello");
String str4 = new String("Hello");
  1. new 키워드로 생성할 때마다 heap 에 새로운 String 객체 생성
  2. String Constant Pool 에 “Hello” 가 이미 있더라도, 새로운 객체 생성
  • 메모리 낭비의 가능성이 있다
  • 서로 다른 객체이므로 == 연산자가 아니라 equals() 메소드로 객체의 내용을 비교해야 한다.

 

❓StringBuilder 와 StringBuffer

✅ 특징

  • String 연산에서 문제점을 해결하기 위해서 등장!
    → 문자열을 더할 때, 기존의 데이터에 저장하는 방식 사용하므로 메모리 낭비가 적고, 속도가 빠르다.
  • Mutable (가변)
  • StringBuilder와 StringBuffer 두 클래스의 큰 차이점은 Thread Safety & 성능

✅ StringBuilder

StringBuilder sb = new StringBuilder();

@Override
public StringBuilder append(String str) {
    super.append(str);
    return this;
}
  • StringBuffer 보다 더 빠름!

✅ StringBuffer

StringBuffer sb = new StringBuffer();

@Override
public synchronized StringBuffer append(String str) {
    toStringCache = null;
    super.append(str);
    return this;
}
  • Thread-Safe
  • lock을 걸고 푸는 오버헤드 때문에 속도가 느리므로 남발하면 안된다!

 

정리

  • 문자열 변경이 빈번하지 않다! → String
  • StringBuffer
    • 문자열 변경 빈번 && 멀티쓰레드 환경O
    • static 으로 선언된 문자열 변경 시
  • StringBuilder
    • 문자열 변경 빈번 && 멀티쓰레드 환경X
    • 메서드 내에서 지역 변수로 사용할 때

UTF

❓ 무엇인가?

  • 유니코드(Unicode) 를 인코딩하기 위한 표준
  • 각 문자를 특정한 이진 형식으로 변환하는 방법을 정의

*유니코드 : 각 문자를 고유한 숫자로 매핑한 것

 

❓종류

✅ UTF-8

  • 가변 길이 인코딩 방식 (문자에 따라 1-4byte. 영어는 1byte)
  • 메모리 효율적

✅ UTF-16

  • 대부분의 문자를 2byte로 처리함

✅ UTF-32

  • 고정 길이 인코딩 방식 (모든 문자를 4byte)
  • 메모리 비효율적 but, 간단함!

대소문자 구분에 대하여..

❓대소문자 구분은 중요할까?!

YES! 대소문자 구분 여부는 데이터베이스의 정렬 규칙(Collation) 과 밀접한 연관이 있므므로 중요하다!

  • 대소문자 구분이 필요한 경우 : 제품코드, 비밀번호 등
  • 대소문자 구분 필요없는 경우 : 이름, 주소 검색 등

❓MySQL Collation

CHAR, VARCHAR, TEXT 과 같은 문자열 Datatype 에는 Character setCollation 이라는 속성이 있다.

 

✅ Character set

  • 각 문자가 컴퓨터에 저장될 때 어떠한 ‘코드’로 저장될지에 대한 규칙의 집합
  • 저장공간의 크기
    • latin1 (2바이트) , utf8 (가변3바이트) , utf8mb4 (가변4바이트)
  • 프로그램과 데이터베이스가 문자를 주고받을 때 charset만 설정하면 됨!

✅ Collation

  • 특정 Character set 에 의해 DB에 저장된 값들을 ‘비교, 검색’ 하거나 문자들을 서로 ‘정렬’ 등의 작업을 위해 비교할 때 사용하는 규칙의 집합
  • TEXT 데이터를 정렬(ORDER BY)할 떄 사용
  • 종류
    • utf8_general_ci: 대소문자 구분을 하지 않는 Collation
    • utf8_bin: 대소문자 구분을 하는 Collation

 

💬 Emoji

원래는 전 세계 모든 언어가 21bit 에 저장되기 때문에, mysql 에서 utf8 을 3바이트 가변 자료형으로 설계했다.

→ 널리 사용되던 MYSQL / MariaDB 의 구축 환경은 charset-utf8 , collation-utf8_general_ci 였다.

⏩ 하지만….. Emoji 문자열은 모두 4 Byte !!

  1. 이모지와 같은 4Byte 문자열을 utf8 에 저장하니까 손실되는 문제 발생.
  2. 가변-4바이트 UTF-8 문자열 저장 가능게끔 하는 utf8mb4 라는 charset 추가!

(+) 기존 utf8 시스템을 utf8mb4 로 바꿔도 값의 손실은 없다.

profile
BE Developer

0개의 댓글