전체 글

전체 글

    [Sort] 셸 정렬 (Shell Sort)

    소개 삽입정렬의 단점을 보완하고자 나온 셸 정렬이다. 간격(gap) 에 맞추어 삽입정렬을 하는 정렬이다. O(n2)의 시간복잡도를 가지지만 삽입정렬보단 효율적이다. 동작원리 배열의 길이 / 2 를 gap 으로 설정 첫번째 인덱스 부터 gap에 맞는 요소들을 삽입 정렬 진행 위의 순서 반복 구현 코드 public static int[] sort(int[] nums) { int length = nums.length; for (int gap = length / 2; gap > 0; gap /= 2) { for (int startIndex = 0; startIndex < gap; startIndex++) { insertionSort(nums, startIndex, gap); } } return nums; } p..

    [Sort] 삽입 정렬 ( Insertion Sort)

    소개 정렬되지 않은 부분의 자료가 정렬된 부분의 자리로 삽입되는 형태의 정렬 방법이다. 동작원리 첫번째 자리는 정렬이 되었다고 가정한다. 두번째 자리를 target 으로 정하고 왼쪽의 정렬된 원소들과 target의 값을 비교한다. 만약 target 값보다 정렬된 왼쪽 원소들이 크다면 자리를 교환해준다. 다시 오른쪽으로 이동하여 target값을 저장하고 위의 순서대로 반복한다. 구현 코드 for (int i = 1; i = 0 && arr[j] > target; j--) { arr[j + 1] = arr[j]; } arr[j + 1] = target; }

    [Sort] 선택 정렬 (Selection Sort)

    소개 리스트 안의 자료중 가장 작은수 또는 가장 큰수를 찾아 첫 번째 위치 또는 가장 마지막 위치의 수와 교환해주는 정렬이다. 교환 횟수를 최소화하는 반면 비교하는 횟수는 증가한다. 동작원리 배열의 순서와 상관 없이 선택 정렬되는 배열은 n -1 의 교환이 이루어진다. 버블 정렬 보다 교환 횟수는 적어지지만 비교를 모든 원소를 해야하기 때문에 n2의 비교가 이루어진다. for (int i = 0; i < arr.length; i++) { int minIndex = i; for (int j = i; j < arr.length; j++) { if (arr[minIndex] < arr[j]) { continue; } minIndex = j; } int temp = arr[i]; arr[i] = arr[minI..

    [Sort] 버블 정렬 (Bubble Sort)

    소개 탐색의 효율적인 방법중 하나가 정렬이다. 정렬한 뒤 탐색을 하면 탐색의 효율성이 높아진다. 정렬 알고리즘 중 하나가 버블 정렬이다. 특징 버블 정렬은 단 두개의 요소만 정렬해주는 좁은 범위의 정렬이다. 하나의 요소를 정렬하기 위해 너무 많이 교환하는 낭비가 발생 될 수 있다. 동작원리 리스트 안에 들어있는 두 개의 인접한 수를 비교 만약 순서에 맞지 않는다면 교환 예시 배열 [5, 1, 6, 2, 4, 3] 이 있다고 가정 5와 1을 비교, 1이 5보다 작기 때문에 교환이 됨 5와 6을 비교, 5가 6보다 작기 때문에 그 다음 요소로 넘어감 6과 2를 비교. 2가 6보다 작기 때문에 교환이 됨 6과 3 비교, 3이 6보다 작기 때문에 교환 위의 단계별로 배열결과를 써보자. [5, 1, 6, 2, 4..

    [Sort] 선형 탐색 (Linear Search)

    소개 원하는 자료를 찾을때 까지 처음부터 마지막 자료까지 순서대로 탐색한다. 단점 자료를 찾을때 까지 모든 자료를 확인해야하는 부담감이 있다. 즉, 효율적이지 않다. 리스트의 길이를 n이라 가정 찾을 자료가 마지막에 있을 시 처음부터 마지막 자리까지 확인해야한다. 결국엔 n 번 확인해야한다. 정렬 리스트 vs 무작위 리스트 대규모 데이터와 정렬된 리스트를 탐색할 땐 선형 탐색의 효율성이 떨어지지만 정렬되지 않은 무작위 리스트를 탐색할 땐 효율성이 좋다.

    [Java] Java 에서 파일을 읽는 여러가지 방법

    목표 클래스 경로, URL에서 파일을 로드하는 방법 BufferedReader, Scanner, StreamTokenizer, DataInputStream, SequenceInputStream 및 FileChannel 사용하여 읽는 방법 UTF-8로 인코딩된 파일을 읽는 방법 입력 파일 읽는 방법 읽을 파일을 준비한다. test.txt Hello, World! 파일을 읽는 메서드를 준비한다. public class HelperFactory { public static String readFromInputStream(InputStream inputStream) throws IOException { StringBuilder sb = new StringBuilder(); try (BufferedReader b..

    [Java] What is Serialization in Java?

    직렬화란? JVM 메모리 내 스택과 힙영역에 저장되어 있는 객체를 외부에서 사용할 수 있도록 Byte 형태로 변환하는 과정을 직렬화라고 한다. 직렬화와 역직렬화를 통칭하여 직렬화 기술이라 말한다. 사용하는 이유? 서로 다른 가상메모리 공간에서 데이터를 통신하고 싶다. 참조값(주소값) 으로 전달하면 사용할 수 있을까? 다른 환경에서 주소값을 알고 있어도 독립적인 특징을 가지고 있는 가상메모리에서 의미가 없어진다. 하지만 직렬화를 사용하여 데이터를 바이트 형태로 변환하고 전달하면 받는 쪽에서 역직렬화를 하여 데이터를 얻어올 수 있다. 직렬화의 조건 implement Serialization 상위 클래스가 Serialization 인터페이스를 구현 한 경우 상속관계의 클래스 중 상위 클래스가 Serializa..

    [Java] ArchUnit 아키텍처 테스트에 대해 알아보자

    [Java] ArchUnit 아키텍처 테스트에 대해 알아보자

    아키텍처 테스트 소개 개발 공부를 하면서 단위 테스트 통합 테스트 등에 대한 내용들은 익숙해졌다. 위에서 말한 2가지 테스트 외에도 속성 테스트와 아키텍처 테스트 등 여러 테스트가 존재하는데 오늘은 아키텍처 테스트에 대한 내용과 패키지 종속성 검사와 클래스 종속성 검사에 대한 테스트를 알아볼 것입니다. 나머지 deep 한 내용들은 하단에 reference 링크가 있으니 관련 테스트를 할 시에 참조하여 살펴봅시다. 아키텍처란 건축학이라는 뜻을 가지며 소프트웨어에선 시스템의 구성을 뜻합니다. 이러한 뜻을 보며 아키텍처 테스트를 생각해보면 “패키지 구조와 클래스 간의 관계 등을 테스트해 볼 수 있을 것이다”라고 예측할 수 있습니다. 아키텍처 테스트의 목적은 아키텍처의 패키지, 클래스, 레이어, 슬라이스 간의 ..

    BootStrap DropDown 기능 적용이 안될 때

    드랍 다운 기능 적용이 안될 때 js 적용 링크를 css 적용 링크보다 먼저 배치 해야한다. 참조 http://daplus.net/javascript-%EB%B6%80%ED%8A%B8-%EC%8A%A4%ED%8A%B8%EB%9E%A9-%EB%93%9C%EB%A1%AD-%EB%8B%A4%EC%9A%B4-%EB%A9%94%EB%89%B4%EA%B0%80-%EC%9E%91%EB%8F%99%ED%95%98%EC%A7%80-%EC%95%8A%EC%9D%8C/

    [Spring JPA] 트랜잭션은 언체크, 체크 예외에 대해 어떻게 커밋과 롤백을 처리할까?

    [Spring JPA] 트랜잭션은 언체크, 체크 예외에 대해 어떻게 커밋과 롤백을 처리할까?

    언체크 예외 발생 시 예외 처리를 했는데도 RollBack 이 되어 데이터베이스에 반영이 안되고 체크 예외 발생 시 예외 처리를 하고 결과를 보면 Commit이 되어 데이터베이스에 반영이 된다. 이게 어떻게 동작하는 걸까? 동작을 알아보기 전에 먼저 언체크 예외와 체크 예외에 대해 개념을 살펴보자. 언체크 예외는 RuntimeException 클래스를 상속한 예외를 말한다. 컴파일러가 에러 난 부분을 체크 하여 알려주지 않아 언체크 예외라고 생각하면 될 것이다. 체크 예외는 언체크 예외를 제외한 예외를 말한다. 컴파일러가 체크를 한 예외여서 체크 예외라고 생각하면 된다. 언체크, 체크 개념을 알아보았으니 트랜잭션 단위에서 예외 처리를 진행해 커밋과 롤백의 동작을 테스트 해보자. 예외를 던지다 @Trans..

    [Spring JPA] CASCADE 는 무엇일까?

    [Spring JPA] CASCADE 는 무엇일까?

    앞서 영속성 컨텍스트에 대해 정리하고 fetch의 대해 정리 해보았다. CASCADE 란 종속이란 단어인데 DB 쿼리 에서도 보았을 것이다. JPA에서는 A라는 엔티티에 연관된 엔티티들도 영속성 상태로 만들고 싶을때 사용하는 속성이다. @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) CascadeType 타입에서도 여러가지가 있다. 주로 ALL, PERSIST 을 설정하여 사용한다. 주의! 속성을 지정할땐 연관된 엔티티의 소유자가 단 하나일때 만 사용해야한다. 소유자가 여러개이면 한쪽에서 변경할 시 다른 한쪽에서도 변경된 값으로 영향을 받으므로 사용하지 않는 것을 권장한다. 고아 객체 관리 말 그대로 풀어서 설명해보면 소유자가 없는 객체 즉,..

    [Spring JPA] N + 1의 문제점이 무엇이고 어떻게 해결 해야할까?

    [Spring JPA] N + 1의 문제점이 무엇이고 어떻게 해결 해야할까?

    N + 1의 문제점에 대해 알아보기 전에 지연로딩 과 즉시로딩 을 알아야한다. 글 뜻대로 풀어서 생각해보면 지연로딩은 쿼리를 지연시켜서 로딩시킬 것이고 즉시로딩은 쿼리를 즉시 로딩시킬것이라고 생각이 된다. JPA 에 적용 시켜 즉시로딩과 지연로딩을 알아보자. Member 엔티티에 @ManyToOne N : 1 의 관계를 맺은 Team 엔티티가 존재한다 가정해보자. Member @Getter @NoArgsConstructor @Entity @Table(name = "members") public class Member { @Id @GeneratedValue @Column(name = "member_id") private Long id; private String name; @ManyToOne @JoinCo..

    [Spring JPA] 프록시 객체는 어떻게 동작할까?

    [Spring JPA] 프록시 객체는 어떻게 동작할까?

    기존의 조회하는 기능을 사용하면 select 쿼리가 바로 나갔다. 하지만 getReference() 로 호출하면 쿼리가 안나가고 생성된 엔티티를 사용할 시(getName()) 에 select 쿼리가 나간다. 쿼리가 지연되는 상황이 보여진다. 이게 어떻게 동작이 되는 걸까? 먼저 프록시 객체라는 것을 알아야 한다. 하이버네이트가 만들어주는 프록시 객체는 Entity 타입의 target 참조변수가 존재 한다. 이 객체를 사용시에 영속성 컨텍스트에 초기화를 요청하고 영속성 컨텍스트는 DB에 원본 엔티티를 조회하고 생성 한다. 다음으로 프록시 객체가 원본 엔티티를 생성하여 getName() 로 호출 하여 사용한다. 위의 내용을 그림으로 보면 이해할 것이다. 프록시 객체의 특징을 살펴보자 프록시 객체는 처음 사용..

    [Spring JPA] 객체지향의 상속관계 매핑은 어떤 전략을 사용할까?

    [Spring JPA] 객체지향의 상속관계 매핑은 어떤 전략을 사용할까?

    관계형 데이터베이스에는 상속 관계가 없다. 대신 서브타입과 슈퍼타입의 모델링 기법이 존재한다. 공통의 속성을 뽑아 슈퍼타입으로 만들고 나머지 속성은 서브타입으로 설정을 하면 상속 관계와 비슷하게 설계가 된다. 아래 그림을 참조해서 보자. 이러한 테이블 구조를 객체에서 매핑하는 전략을 알아보자. 전략 3가지 조인 전략 단일 테이블 전략 구현 클래스마다 테이블 전략 1. 조인 전략 슈퍼타입과 서브타입의 테이블을 각각 생성 Item @Entity @Getter @NoArgsConstructor @DiscriminatorColumn -> 핵심 @Inheritance(strategy = InheritanceType.JOINED) -> 핵심 public class Item { @Id @GeneratedValue p..

    [Spring JPA] 객체의 연관관계는 어떻게 관계를 맺는것이 좋을까?

    관계형 데이터베이스의 연관관계는 외래키(FK)를 참조하여 다른 테이블과 맺습니다. 그렇다면 객체는 연관관계를 어떻게 맺으면 좋을까요? 객체는 연관관계를 맺을 다른 객체를 참조(Reference) 하여 연관관계를 맺습니다. 방향성 또한 테이블은 양방향 연관관계를 가지고 객체는 단방향 연관관계를 가지는 것이 큰 차이점입니다. 이 불편한 패러다임 불일치를 해소시켜주는 것이 Spring JPA 입니다. JPA를 사용하여 연관관계를 맺어보겠습니다. 🔴 연관관계 맺어보기 먼저 테이블에서는 외래키(FK)를 참조하여 다른 테이블과 연관관계를 맺는건 알고 계실 겁니다. 테이블처럼 연관관계를 맺어보면 방문기록 객체에 유저 객체의 PK값을 참조하려면 아래 코드처럼 코드를 작성해야합니다. @Entity public class..