yaml파일을 접하게 되어 yaml파일이 무엇인지 간단히 남겨두고자 한다.

 

 

YAML : 사람이 읽을 수 있는 데이터 직렬화 언어로서, 구성 파일 작성에 자주 사용됨.

  • 확장자 : .yml 또는 .yaml
  • 특정 구문 규칙
    • # (해시기호) : 코멘트. 여러 줄의 코멘트를 지원하지 않으므로 각 줄 맨 앞에 위치할 것
    • --- : 문서의 시작
    • ... : 문서의 끝
  • 파일 구조는 맵 또는 목록으로 들여쓰기와 키-값 정의 방식에 따라 계층 구조로 이루어져 있음
    • 맵 구조 : 키-값 쌍으로 이루어져있음. 키는 고유해야하고 순서는 상관 없음
    • 목록 구조 : 대시(-) 및 공백으로 시작하고 들여쓰기로 상위 항목과 구분함
      • => 목록 시퀀스는 배열과 같고 목록은 맵 구조에 포함 가능
  • 사용 : configuration 파일을 만들거나 쿠버네티스 리소스 및 배포, GitHub와 같은 소스 제어에 사용됨

 yaml 파일은 생성 후 파일이 유효한지 확인할 때 linter라는 앱을 사용해 파일 구문을 검증하고, yaml 파일 생성 후 앱에 전달하기 전 yamllint라는 커맨드로 유효성을 확인 할 수 있다.

 

 

(참고에 있던 예제. 코멘트, 시작 표시, 키-값 맵 구조 안 배열 구조가 있는 것을 볼 수 있다. )

#Comment: Student record
#Describes some characteristics and preferences
---
name: Martin D'vloper #key-value
age: 26
hobbies: 
  - painting #first list item
  - playing_music #second list item
  - cooking #third list item
programming_languages:
  java: Intermediate
  python: Advanced
  javascript: Beginner
favorite_food: 
  - vegetables: tomatoes 
  - fruits: 
      citrics: oranges 
      tropical: bananas
      nuts: peanuts
      sweets: raisins

 

 

 

 

참고 : https://www.redhat.com/ko/topics/automation/what-is-yaml

 

 

# 문제

H-Index는 과학자의 생산성과 영향력을 나타내는 지표입니다. 어느 과학자의 H-Index를 나타내는 값인 h를 구하려고 합니다. 위키백과1에 따르면, H-Index는 다음과 같이 구합니다.

어떤 과학자가 발표한 논문 n편 중, h번 이상 인용된 논문이 h편 이상이고 나머지 논문이 h번 이하 인용되었다면 h의 최댓값이 이 과학자의 H-Index입니다.

어떤 과학자가 발표한 논문의 인용 횟수를 담은 배열 citations가 매개변수로 주어질 때, 이 과학자의 H-Index를 return 하도록 solution 함수를 작성해주세요.

 

# 제한사항

과학자가 발표한 논문의 수는 1편 이상 1,000편 이하입니다.

논문별 인용 횟수는 0회 이상 10,000회 이하입니다.

 

# 입출력 예

citations return
[3, 0, 6, 1, 5] 3

# 입출력 예 설명

이 과학자가 발표한 논문의 수는 5편이고, 그중 3편의 논문은 3회 이상 인용되었습니다. 그리고 나머지 2편의 논문은 3회 이하 인용되었기 때문에 이 과학자의 H-Index는 3입니다.

 

 

# 문제 풀기

- 접근

1. 0부터 시작하는 반복문을 돌려서 h값보다 큰 값이 h개 이상, h개 이하 이면 h값

h = 2이면 3,6,5로 3편의 논문이 2번 이상 인용되었고, 0, 1로 2편이 2번 이하 인용됨 => 가능

h = 3이면 마찬가지로 가능 => 최댓값

h는 h번이상 인용된 h개보다 같거나 작고, h번 이하 인용된 h개보다 같거나 크다 => h는 n보다 같거나 작다

그 중 h의 최댓값 리턴하기

public int solution(int[] citations) {
    int answer = 0;

    int h = citations.length;
    while(h > 0) {
        int over = 0;
        int below = 0;
        // 파라미터로 받은 배열의 요소 하나하나 비교
        for(int e : citations) {
            if(e == h) {
                over++;
                below++;
            } else if (e > h) {
                over++;
            } else {
                below++;
            }
        }
        if(h <= over && h >= below) {
            return h;
        }
        h--;
    }
    return answer;
}

=> 정답

테스트 11 통과 (2.80ms, 78.1MB)
테스트 12 통과 (0.04ms, 73.2MB)

 

- 그 외 다른 풀이(프로그래머스 - 다른 사람의 풀이)

import java.util.Arrays;

class Solution {
    public int solution(int[] citations) {
        int answer = 0;
        Arrays.sort(citations);
        for(int i=0; i<citations.length; i++){
            int smaller = Math.min(citations[i], citations.length-i);
            answer = Math.max(answer, smaller);
        }
        return answer;
    }
}

풀이 해석하기

1. 주어진 배열을 오름차순으로 정렬

2. 배열 길이만큼 반복하면서, 배열 요소(첫요소부터)와 배열 길이를 비교하여 작은 값을 smaller에 저장(h값)

3. 저장된 smaller과 반복문 바깥 answer값과 비교하여 그 중 큰 값 리턴(h 최대값)

=> [3, 0, 6, 1, 5]일 경우

  [0,1,3,5,6] -> 0 vs 5 => 0 / 1 vs 4 => 1 / 3 vs 3 => 3 / 5 vs 2 => 3 / 6 vs 1 => 3

테스트 11 통과 (1.07ms, 79MB)
테스트 12 통과 (0.62ms, 75.2MB)

 

# 느낀점

Math 클래스 메서드 활용해보기

 

'알고리즘 > 코딩테스트' 카테고리의 다른 글

프로그래머스 - 정렬 - 가장 큰 수  (1) 2023.10.26

# 문제 설명

0 또는 양의 정수가 주어졌을 때, 정수를 이어 붙여 만들 수 있는 가장 큰 수를 알아내 주세요.

예를 들어, 주어진 정수가 [6, 10, 2]라면 [6102, 6210, 1062, 1026, 2610, 2106]를 만들 수 있고, 이중 가장 큰 수는 6210입니다.

0 또는 양의 정수가 담긴 배열 numbers가 매개변수로 주어질 때, 순서를 재배치하여 만들 수 있는 가장 큰 수를 문자열로 바꾸어 return 하도록 solution 함수를 작성해주세요.

 

# 제한 사항

numbers의 길이는 1 이상 100,000 이하입니다.

numbers의 원소는 0 이상 1,000 이하입니다.

정답이 너무 클 수 있으니 문자열로 바꾸어 return 합니다.

 

# 입출력 예

numbers return
[6, 10, 2] "6210"
[3, 30, 34, 5, 9] "9534330"

 

# 풀이

1. 경우의 수를 다 만든 다음 가장 높은 수를 리턴?

=> 그러면 반복문을 돌리기가.. 모든 경우의 수 돌리기 => 너무 오래걸릴 듯

 

2. String 타입으로 변환해 크기 정렬해 붙혀 리턴

=> 6, 61, 68 등의 경우 가장 큰 값이 나오지 않음

그래도 일단 식 써보기

  * int -> String 방법

    1. Integer.toString(int)

    2. Integer.valueOf(int)

    3. int + ""

 

public String solution(int[] numbers) {
    String answer = "";
    
    int num = numbers.length;
    String[] temp = new String[num];
    for(int i = 0; i < num; i++) {
        temp[i] = Integer.toString(numbers[i]);
    }
    Arrays.sort(temp, Collections.reverseOrder());

    if(temp[0] == "0") {
        return "0";
    }

    StringBuilder sb = new StringBuilder();
    for(String e : temp) {
        sb.append(e);
    }
    answer = sb.toString();

    return answer;
}

=> 틀림

 

 

3. 인터넷 서칭

3-1. Arrays.sort() 내부에서 Comparator의 compareTo()를 이용하는 방식

Arrays.sort(arr, (o1, o2) -> (o2 + o1).compareTo(o1 + o2));

 

compareTo() 란?

(String 클래스의 compareTo() ) : 두 개의 값을 비교하여 int값으로 반환하는 메서드

Comparable 인터페이스의 compareTo(T o)

- Comparable 인터페이스는 이를 구현하는 각 클래스의 객체를 비교해 객체의 전체 순서를 적용함

- 자기 자신과 매개변수를 비교한다

   a.compareTo(b);

- null값 처리, 오버플로우 방지로 <,>,== 으로 대소비교를 해주는 것이 안전하다

 

(cf. Comparator compare(T o1, T o2))

더보기

- 두 매개변수 객체를 비교(자기 자신과 비교 X)

  => 비교를 위해서 Comparator를 구현하는 객체 안 compare() 메서드를 사용해야함

       어떤 객체든지 상관 없지만 일관성이 떨어진다

  => 기능만 사용하고자 익명 객체(클래스)를 사용

 

compareTo()를 정렬에 사용하기

compareTo() 사용 : 사용자가 정의한 기준으로 값 비교하여 int값 리턴

정렬에 사용

=> Arrays.sort(), Collections.sort() 모두 오름차순으로 정렬

    (오름차순 : compareTo()를 사용했을 때 음수인 경우- 양수면 원소 위치 바꿈)

 

# 따라서,

Arrays.sort(arr, (o1, o2) -> (o2 + o1).compareTo(o1 + o2));

o1과 o2를 정렬할 때,

o2+o1이 o1+o2보다 크면 둘의 위치 변경 => 두 값을 붙혔을 때 큰 수가 앞으로 오게 정렬됨

 

public String solution(int[] numbers) {
    String answer = "";
    
    int num = numbers.length;
    String[] temp = new String[num];
    for(int i = 0; i < num; i++) {
        temp[i] = Integer.toString(numbers[i]);
    }
    
    // 정렬 방식 - 두 값을 붙혔을 때 더 크게 나오는 순으로 정렬
    Arrays.sort(temp, ((o1, o2) -> (o2 + o1).compareTo(o1 + o2)));
	
    // String 값이기 때문에 == 으로 판별이 제대로 되지 않음!
    if(temp[0].equals("0")) {
        return "0";
    }

    StringBuilder sb = new StringBuilder();
    for(String e : temp) {
        sb.append(e);
    }
    answer = sb.toString();

    return answer;
}

 

 

 

참고

3-1.

- https://bellog.tistory.com/170

compareTo().

- https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html#method.summary

- https://st-lab.tistory.com/243

'알고리즘 > 코딩테스트' 카테고리의 다른 글

프로그래머스 - 정렬 - H-Index  (1) 2023.10.28

실시간 통신 기술

1. Short Polling

2. Long Polling

3. SSE(Server-Sent-Events)

4. WebSocket

 

1. 폴링(Short Polling)의 경우

기본적인 HTTP 통신을 기반으로 호환성이 좋지만, 업데이트 주기에 따라 실시간 데이터 갱신의 문제나 불필요한 서버 부하가 발생할 수 있다

 

2. 롱 폴링 (Long Polling)

업데이트가 있을 때마다 실시간으로 데이터가 들어와서 과부하가 줄어들었지만 이 방식도 데이터 업데이트가 빈번하게 일어나면 연결을 위한 요청도 똑같이 발생하므로 서버에 부하가 일어날 수 있음

(⇒ 프로젝트에서 웹채팅 구현 시 채택하지 않음)

 

3. SSE(Server-Sent-Events)

서버와 한번 연결을 맺고 나면, 일정 시간 동안 서버에서 변경이 발생할 때마다 서버에서 클라이언트로 데이터를 전송하는 방법

⇒ 한 번만 연결 요청을 보내면, 연결이 종료될 때까지 재연결 과정 없이 서버에서 웹 브라우저로 데이터를 계속해서 보냄

(But. 서버 → 웹 브라우저로만 데이터 전송 가능, 최대 동시 접속 횟수 제한)

SSE의 특징

  • 클라이언트는 서버를 구독(SSE Connection을 맺는다.)
  • 서버는 변동사항이 생길 때마다 구독한 클라이언트들에게 데이터를 전송한다.
  • websocket과 달리 별도의 프로토콜을 사용하지 않고 HTTP 프로토콜만으로 사용이 가능하며 훨씬 가볍다.
  • 접속에 문제가 있으면 자동으로 재연결을 시도한다.
  • 최대 동시 접속 수는 HTTP/1.1의 경우 브라우저 당 6개이며, HTTP/2는 100개까지 가능하다.
  • IE를 제외한 브라우저에서 지원된다.(Polyfills을 사용하면 가능하다고 한다.)
  • 이벤트 데이터는 UTF-8 인코딩된 문자열만 지원한다. 일반적으로 JSON으로 전송한다.
  • 클라이언트에서 페이지를 닫아도 서버에서 감지하기가 어렵다.

       => 웹소켓을 사용하는 이유

  • 단점 : 초기 구현에 상당히 많은 비용이 든다. 연결 유지에 비용이 들어 트래픽 양이 많아지면 서버에 큰 부담이 된다. 멀티 온라인 게임등의 실시간 상태 업데이트와 긴밀한 동기화를 통해 분산된 사용자에게 전송해야 하는 경우 유용
       ⇒ 시스템에 상당한 복잡성을 추가하고 구현하는데 많은 투자가 필요. 폴링or SSE 가 적합하지 않은 경우에만 사용
  • 웹소켓은 속도가 빠르다는 큰 장점이 있다. 연결을 매번 하지 않아도 되고 연결이 설정되면 데이터는 어느 방향으로든 즉시 안전하게 전송됨(TCP이기에 메시지가 항상 군서대로 도착하도록 보장됨). 채팅, 게임, 주식 차트 등에 사용

 

4. WebSocket 프로토콜

  • ws 프로토콜을 기반 (http/https 에서 ws/wss로 변경)
  • AJAX : HTTP를 사용하기 때문에 요청을 해야 응답이 옴(버튼을 누르거나 일정 시간주기로 요청을 보내야함)
  • HTTP와는 다른 통신 프로토콜로 웹 서버와 웹 브라우저서로 실시간 메시지를 교환하는 데에 사용
  • 클라이언트와 서버 사이에 지속적인 완전 양방향 연결 스트림을 만들어 주는 기술
  • 웹소켓 연결을 맺기 위한 첫 번째 핸드셰이크를 주고받은 이후 지속적으로 연결이 유지되는 것이 특징
     ⇒ 매번 메시지 전송 시에 새롭게 연결을 맺을 필요가 없어 빠르고 효율적이다
  • 일반적인 웹소켓 클라이언트는 사용자의 브라우저일 것이지만, 그렇다고 해서 이 프로토콜이 플랫폼에 종속적이지는 않음
  • Spring 스펙에서 Web에 속해있다(Spring 4.0 환경에 새로 들어온 네트워크 서비스)

   SockJS, Socket.io를 사용

 

그 외

STOMP(Simple Text Oriented Messaging Protocol)이 있다.

 

 

참고

- https://taemham.github.io/posts/Implementing_Notification/

- https://velog.io/@max9106/Spring-SSE-Server-Sent-Events%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%8B%A4%EC%8B%9C%EA%B0%84-%EC%95%8C%EB%A6%BC

- https://dkswnkk.tistory.com/702

- https://innu3368.tistory.com/213

 

예전에 했던 프로젝트를 Node.js를 사용하여 만들어볼까한다.

인텔리제이에서 Node.js 새 프로젝트를 생성하는 것부터 시작해본다.

(참고블로그 : https://kkumalog.tistory.com/entry/Nodejs-Create-Nodejs-Project-in-IntelliJ-IDEA)

 

# 프로젝트 생성

1. File - New - Project...

2. New Project - Generators - Express 선택

3. Name에 프로젝트 이름 작성, Location에 원하는 위치 설정

4. Options - View Engine : EJS 설정 후 Create  => 설치 완료

 

 

이러면 끝인줄 알았는데 EJS 플러그인을 설치해야 작동한다

 

# 플러그인 설치

1. File - Settings

2. Plugins - Marketplace 에서 EJS 플러그인 Install

    (설치된 플러그인은 Installed탭에서 확인할 수 있다)

 

 

# 서버 실행

1. 생성한 프로젝트 폴더 안에 app.js를 실행한다

2. http://localhost:3000/ 를 실행하면 Welcome to Express 가 출력된 것을 볼 수 있다

 

 

+ Recent posts