String/StringBuilder/StringBuffer (항해일지 5일차)

김형준·2022년 5월 13일
0

TIL&WIL

목록 보기
5/45

chapter2 알고리즘 주차가 시작되었다.

1) 학습일지

오전에는>
알고리즘 주차의 발제 세션을 들었고, 새로운 팀원 분들과 간단히 소통했다.
또한 InteliJ IDE(Ultimate)를 설치하여 Java 환경 세팅을 마무리했다.

이번 주의 과제는 크게 두 가지로, 아래와 같다.
1. 40~ 53개의 알고리즘 문제 풀이
2. OOP 구현 코드 작성

주간 계획을 세우기 위해 각자 4번 까지의 문제를 풀었고, OOP 구현 과제의 틀을 잡았다. (알고리즘은 주특기 언어인 Java로 풀어야해서, 파이썬으로 풀 때에 비해 조금 더 시간이 걸릴 것 같다.)

오후에는>
4번 까지의 알고리즘 풀이 현황을 공유했다. 운 좋게도 팀장님이 전공자였고, 문법 / 성능 관련 팁을 많이 얻을 수 있었다.

  • 그 중 Java의 StringStringBuilder/ StringBuffer의 차이에 대해 알게 되었고 바로 구글링하여 공부했다!

    • String 클래스는 Immutable, 불변성을 지닌다. 따라서 한번 생성되면 할당된 메모리 공간이 변하지 않는다. 즉 연산이 이루어져도 해당 객체가 변하는 것이 아니라 새롭게 문자열을 생성한다. (Heap 메모리 영역에 생성) 따라서 복잡한 코드에서 성능상의 이슈가 발생한다.
    • 반면에 StringBufferStringBuilder는 Mutable, 가변성을 지닌다.
    • 두 클래스는 문자열 연산 등으로 기존 객체의 공간이 부족해지는 경우, 기존의 버퍼 크기를 늘리며 유연하게 동작한다. 심지어 둘이 제공하는 메서드도 동일하다!
    • 그러나 가장 큰 차이는 StringBuffer는 각 메서드 별로 Synchronized Keyword가 존재하여, 멀티스레드 환경에서도 동기화를 지원한다는 것이다.
    • 따라서 멀티스레드 환경에선 StringBuffer를, 싱글스레드 환경에서는 StringBuilder를 사용하는 것이 좋다고 한다. (동기화 관련 처리로 인해 StringBuilder의 성능이 더 좋은 이유도 있다)
  • 그렇다면 멀티스레드, 단일스레드 환경이 무엇일까??...

    <출처: https://velog.io/@gil0127/%EC%8B%B1%EA%B8%80%EC%8A%A4%EB%A0%88%EB%93%9CSingle-thread-vs-%EB%A9%80%ED%8B%B0%EC%8A%A4%EB%A0%88%EB%93%9C-Multi-thread-t5gv4udj>

    • 스레드(thread)란? 프로세스가 할당받은 자원을 이용하는 실행의 단위이다.
    • 한 프로세스 내에서 동작되는 여러 실행 흐름으로 프로세스 내의 힙, 데이터, 코드 영역을 공유한다. 이러한 작업을 담당하는 최소 실행 단위를 스레드라고 한다.
    • 각각의 스레드는 독립적인 작업을 수행해야 하기 때문에 고유한 스레드ID, 프로그램 카운터, 레지스터 집합, 스택 등을 가지고 있다.
    • 멀티스레드란? CPU의 최대 활용을 위해 프로그램 둘 이상을 동시에 실행하는 기술이다. 이러한 작업은 Context Switching(문맥교환)을 통해서 이루어진다. 따라서 동시에 병렬적으로 여러 작업을 수행할 수 있다.
    • context switchig, 동기화 등의 이유로 싱글 코어 멀티 스레딩은 스레드 생성 시간이 오버헤드로 작용해 싱글스레드보다 느리다.
    • 공유하는 자원에 동시에 접근하는 경우, 다른 스레드에서 사용중인 자원을 사용할 때, 제어를 통해 동기화 관리가 추가적으로 이루어져야 한다.
    • 따라서 context switching과 동기화를 신경쓰지 않아도 되는 싱글스레드도 상황에 따라 충분히 장점을 지닌다. (물론 에러 발생 시 프로그램이 죽는 이슈도 있다!)

+) String관련 클래스 결론!

  • 앞으로 하게 될 스프링 프로젝트에서, 내가 작성할 Java코드는 멀티 스레드 환경에서 실행되니 StringBuffer 클래스를 활용하자!!!

  • 정리해보자면!! 내가 작성하는 Java 코드가 어떤 환경에서 실행이 되는 지를 파악하고, 멀티스레드 환경이라면 StringBuffer 클래스를, 싱글스레드 환경이라면 StringBuilder 클래스를 사용하는 것이 성능적으로 이슈를 줄인다는 결론을 얻었다.

  • 이를 앞으로 학습하게 될 스프링 프레임워크에 적용해보자면,

    • Spring Tomcat은 멀티 스레드를 활용한다. (따라서 클라이언트의 수가 많아지면 그 만큼 스레드를 생성/수거하는 비용 및 오버헤드가 발생한다)
    • 이러한 문제를 개선하기 위해 스레드풀(Thread pool)을 사용한다고 하는데,,,, 오늘은 너무 길어지니 다음에 포스팅하며 정리해야겠다.
    • 추가적으로 모든 Spring bean들은 기본적으로 싱글톤 패턴으로 제공된다고 한다.
  • 싱글톤 패턴이 뭔데??

    • 디자인 패턴 중 하나로, 객체의 인스턴스가 오직 1개만 생성되는 패턴을 의미한다!
  public class Singleton {

    private static Singleton instance = new Singleton();
    
    private Singleton() {
        // 생성자는 외부에서 호출못하게 private 으로 지정해야 한다.
    }

    public static Singleton getInstance() {
        return instance;
    }

    public void say() {
        System.out.println("hi, there");
    }
}
  • 최초 한번의 new 연산자를 통해 고정된 메모리만을 사용한다 / 싱글톤 인스턴스는 전역으로 사용되기 때문에 다른 클래스의 인스턴스들이 쉽게 접근할 수 있다.

+) Insight

  • !!! 스프링의 모든 bean들이 싱글톤 패턴으로 제공되는 것은 불변성을 지니기에 Thread-safe를 보장한다는 이점을 지닌다. !!!

시작은 String/StringBuffer/StringBuilder 였지만, 파고파고 들어오다 보니 스프링, 싱글톤 패턴까지 와버렸다. (무의식의 흐름,,)

2) 오늘의 소소한 이슈

  • 삼항 연산자 사용 형식
변수 = (논리 조건) ? true일 때 실행되는 기능 : false일 때 실행되는 기능
  • 앞에 변수를 지정해주지 않으면 오류가 난다. (딱히 성능을 높여주는 것도 아니라, 제한적으로 사용 가능할 것 같다)

  • Arrays.deepToString: 2차원 배열의 경우 toString을 쓸 경우 내부 배열은 주소로 출력되기 때문에 내부 배열도 스트링으로 얻기 위해선 deepToString을 사용해야한다.

  • char 타입 간 뺄셈이 int로 형변환 되는 것.. 은 다음에 공부!
    아스키 코드표에서 십진법 부분이 실제 저장되는 값이고, 의미 부분은 표출되는 값!

3) 코멘트

알고리즘 문제 풀이 시, 정답 처리에만 집중하지 않고 성능면에서도 검토해보기.

알고리즘 강의 들으면서 병행하기!

profile
BackEnd Developer

0개의 댓글