삽입 정렬, 선택 정렬, docker

calis_ws·2023년 5월 16일
0

Insertion Sort(삽입정렬)

i번째 숫자가 어디에 들어가야 하는지를 정하는 모양이 위치를 찾아 넣는 것 같다고 하여 삽입정렬이라는 이름이 붙었다.

i는 0이 아닌 1부터 시작한다.

public class InsertionSort01 {
    public static void main(String[] args) {
        int[] arr = {7, 2, 3, 9, 28, 11};
        // j j j-1
        // 1 1 0
        // 2 2 1
        // 2 1 2
        // 3 3 2
        // 3 2 1
        // 3 1 0
        for (int i = 1; i < arr.length; i++) {
            for (int j = i; j > 0; j--) {
                System.out.printf("i:%d j:%d j-1:%d\n", i, j, j-1);
            }
        }
    }
}

import java.util.Arrays;

public class InsertionSort01 {
    public static void main(String[] args) {
        int[] arr = {7, 2, 3, 9, 28, 11};
        
        for (int i = 1; i < arr.length; i++) {
            for (int j = i; j > 0; j--) {
                if (arr[j] < arr[j - 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j - 1];
                    arr[j - 1] = temp;
                }
            }
        }
        System.out.println(Arrays.toString(arr));
    }
}

로직 완성 튜닝하기

교환 안될때 break

i번째까지 올 동안 해당 숫자 set은 오름차순으로 정렬이 되어 있기 때문에 교환을 못하는 상태가 오면 그 다음번도 역시 교환을 못하는 상태가 된다.

ex)
2 3 7 9 28 11 인 경우
2 3 7 9 11 28은 교환이 되지만
9 11 부터는 교환이 안됨
import java.util.Arrays;

public class InsertionSort02 {
    public static void main(String[] args) {
        int[] arr = {7, 2, 3, 9, 28, 11};

        for (int i = 1; i < arr.length; i++) {
            for (int j = i; j > 0; j--) {
                System.out.printf("i:%d j:%d j-1:%d\n", i, j, j-1);
                if (arr[j] < arr[j - 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j - 1];
                    arr[j - 1] = temp;
                } else {
                    break;
                }
            }
        }
        System.out.println(Arrays.toString(arr));
    }
}

리팩토링

.sort()
내림차순 기능 추가

  • 오버로딩
    메소드 오버로딩은 같은 이름의 메소드를 여러 개 가지되, 매개변수의 유형과 개수가 다른 방식으로 정의하는 것을 의미한다.

내림차순, 오버로딩 적용

import java.util.Arrays;

public class InsertionSort03 {
    public int[] sort(int[] arr, boolean isAscending) {
        for (int i = 1; i < arr.length; i++) {
            for (int j = i; j > 0; j--) {
                System.out.printf("i:%d j:%d j-1:%d\n", i, j, j - 1);
                if ((isAscending ? arr[j - 1] - arr[j] : arr[j] - arr[j - 1]) > 0) {
                    int temp = arr[j];
                    arr[j] = arr[j - 1];
                    arr[j - 1] = temp;
                } else {
                    break;
                }
            }
        }
        return arr;
    }
    public int[] sort(int[] arr) {
        return sort(arr, true);
    }
    public static void main(String[] args) {
        int[] arr = {7, 2, 3, 9, 28, 11};
        InsertionSort03 is = new InsertionSort03();
        arr = is.sort(arr, false); 		// true = 오름차순, false = 내림차순
        System.out.println(Arrays.toString(arr));
    }
}

실제 Overloading 사용 예

courseId → 멋사5기
week → 주차
day → 일차
loginUser → 유저

public List<StudentInfo> getStudentsWithTask(Long courseId, Long week, Long day, UserEntity loginUser){
}
// 주차와 day가 없는 method
public List<StudentInfo> getStudentsWithTask(Long courseId, UserEntity loginUser){
      long week = course시작일 기준 자동계산;
      long day = course시작일 기준 자동계산;
      getStudentsWithTask(week, day);
}

오버로딩을 사용하는 이유가 궁금해졌다.

코드의 가독성 향상 : 오버로딩은 여러 개의 메서드나 연산자를 동일한 이름으로 정의할 수 있게 해줍니다. 
이는 사용자가 메서드나 연산자의 기능을 이름으로 빠르게 이해할 수 있도록 도와줍니다. 
예를 들어, "calculateSum(int a, int b)"와 "calculateSum(double a, double b)"라는 두 개의 메서드가 있다면, 
개발자는 메서드 이름만 보고도 정확한 기능을 유추할 수 있습니다.

일관성 유지 : 동일한 작업을 수행하지만 매개변수의 타입이나 개수가 다른 경우에 
오버로딩을 사용하여 코드를 일관성 있게 유지할 수 있습니다. 
예를 들어, "print(int num)"과 "print(double num)"이라는 두 개의 메서드가 있다면, 
다른 타입의 숫자를 출력하는 경우에도 동일한 메서드 이름을 사용할 수 있습니다.

편의성 제공 : 오버로딩은 사용자에게 편의성을 제공합니다. 
여러 개의 오버로딩된 메서드 중에서 사용자는 자신이 원하는 매개변수 형태에 가장 적합한 메서드를 선택할 수 있습니다. 
이를 통해 사용자는 메서드를 호출할 때 복잡한 형변환을 직접 수행할 필요가 없으므로 코드 작성이 간편해집니다.

다형성 구현 : 오버로딩은 다형성(polymorphism)을 구현하는 데에도 사용됩니다. 
다형성은 객체 지향 프로그래밍의 중요한 개념으로, 동일한 메서드 이름을 사용하여 
다른 매개변수 형태에 대해 다른 동작을 수행할 수 있도록 합니다. 
오버로딩은 이러한 다형성을 구현하는 한 가지 방법입니다.

따라서 오버로딩은 코드의 가독성, 일관성, 편의성 및 다형성 구현을 위해 사용되는 유용한 기능입니다. 
오버로딩을 통해 메서드와 연산자의 이름을 일관되고 의미 있는 방식으로 사용할 수 있으며, 
개발자와 사용자 모두에게 이점을 제공합니다.

출처 - Chat GPT

같은 이름의 메소드라면 뭐가 뭔지 헷갈려서 단점이 아닌가? 라고 생각했지만 의외로 많은 장점을 갖고 있었다.

Selection Sort(선택정렬)

핵심로직 구현

import java.util.Arrays;

public class SelectionSort {
    public static void main(String[] args) {
        int[] arr = {7, 2, 3, 9, 28, 11};
        
        int targetValue = arr[0];
        int targetIdx = 0;
        for (int i = 1; i < arr.length; i++) {
            if (targetValue > arr[i]) {
                targetValue = arr[i];
                targetIdx = i;
            }
        }
        int temp = arr[0];
        arr[0] = arr[targetIdx];
        arr[targetIdx] = temp;

        System.out.println(Arrays.toString(arr));
    }
}

로직 완성

import java.util.Arrays;

public class SelectionSort2 {
    public static void main(String[] args) {
        int[] arr = {7, 2, 3, 9, 28, 11};

        for (int j = 0; j < arr.length - 1; j++) {
            int targetValue = arr[j];
            int targetIdx = j;
            for (int i = j + 1; i < arr.length; i++) {
                if (targetValue > arr[i]) {
                    targetValue = arr[i];
                    targetIdx = i;
                }
            }
            int temp = arr[j];
            arr[j] = arr[targetIdx];
            arr[targetIdx] = temp;
        }
        System.out.println(Arrays.toString(arr));
    }
}

어제자 복습
인스턴스 시작 ~ mysql 설치

docker 명령어

cd ~
docker ps

컨테이너 all 리스트

docker container ls -a

NAME으로 container 정지

docker stop (NAMES)

다운받은 이미지

docker images

nginx 제거

docker rmi nginx

docker container ls -a

컨테이너 아이디 지우기(nginx)

docker container rm (Container ID)

docker container ls -a

nginx redis 띄우기

docker run -d nginx;
docker run -d redis;

모두 지우기

docker system prune -a

리소스 모니터링 glances

glances 설치

apt install glances

모니터링

glances

h 도움말

c CPU

m MEM

Linux 커맨드에서 용량 확인 - df, du
df -h

전체적인 흐름을 볼 수 있다.

du -sh

특정 디렉토리 또는 파일의 흐름을 볼 수 있다.

AWS EC2에 SpringBoot앱을 Gradle, Docker로 빌드


IntelliJ에서 SpringBoot 프로젝트 빌드

SpringBoot 프로젝트 루트(최상단) 위치에 Dockerfile 생성

Github에서 New Repository 생성

IntelliJ에서 프로젝트에 Git 연결

AWS EC2 서버로 연결

EC2 서버에 Java 설치

Github Repository를 EC2 서버에 띄우기

gradle을 사용하여 프로젝트 빌드

SpringBoot 앱 실행 테스트

인바운드 규칙 생성 후 EC2 서버 주소(퍼블릭 IPv4 DNS):포트번호(8080)로 서버 접속

docker로 해당 폴더를 이미지로 빌드

EC2 서버에서 docker로 SpringBoot앱 이미지를 run

8081:8080 포트로 실행

인사이트 타임

알고리즘 보충 수업 16:00 ~ 17:00

회고 시간
ec2 도메인 8081 포트로 접속이 안됐으나 현정님의 피드백으로 접속 성공
8081 port 인스턴스 추가 잊지 말 것. 현정님 감사합니다.

인텔리제이 VCS 메뉴 이슈
시윤님과 태환님 그리고 원기님의 도움으로 VCS 메뉴가 Git 메뉴로 변경된 원인과 해결 방법을 찾아냈다.

git/java 폴더가 Github에 자동 등록이 되어있기 때문에 프로젝트 생성 시마다 java디렉토리로 잡힘.
settings - git에서 계정을 지우고 프로젝트를 생성된 다른 폴더에 생성하면 VCS 메뉴로 변경됨.

review

오늘도 어제와 비슷하게 오전 알고리즘 시간과 나머지는 docker를 이용한 실습 시간을 가졌다. 오후 수업까지 잘 따라가다가 VCS 메뉴 이슈 때문에 수업을 놓쳐 한참을 헤매게 되었다. 새로 생성한 github repository에 push가 안되고 자꾸 기존의 repository에 push가 돼서 진행에 난항을 겪었다.

결국 어찌저찌 혼자 해결하고 강사님 유튜브를 보며 부랴부랴 따라가서 완료할 수 있었다. 두 시간을 헤맸지만 그래도 해결하고나니 묵었던 스트레스가 단번에 풀리는 기분은 역시 단연 최고였다. 이 맛 때문에 욕나와도 계속 하게되는 것 같다.

내일부터 DB 들어간다고 하시는데 기대와 걱정이 반반이다. 포기만 하지 말자 할 수 있 다.

profile
반갑습니다람지

0개의 댓글