1.Blocking/Non-blocking은 타 작업이 진행될 경우
작업에게 제어권이 있는지 없는지에 대한 차이라고 볼 수 있다.
제어권이 주어질 경우 해당 작업이 끝날 때까지 기다려야 하지만
제어권이 바로 반환될 경우 타 작업을 하며 기다릴 수 있다는 차이가 있다.

라면을 끓이는 것으로 Blocking/Non-blocking의 예시를 들자면

Blocking은 
"라면을 사올 때(동작)"까지는 라면을 끓일 수 없기 때문에 
라면을 사올 때(동작완료)까지 기다려야 하는 상황이고

Non-blocking은 

"라면을 위해 물을 끓이는(동작)" 동안
들어갈 부재료들을 손질하거나 면 또는 스프를 끓기 전 넣는 등
다른 작업을 이어갈 수 있는 것은 Non-blocking이라고 볼 수 있다.

 


2.Synchronous/Asynchronous는 호출 여부라고 볼 수 있다.
작업을 실행시켰을 경우 그 작업을 감시해야 하는지
아니면 그 작업이 완료되고 알려주는지 여부가 다르다.
즉 감독여부라고 볼 수 있다.

Non-blocking이라고 가정할 때 
Synchronous는 코딩을 열심히 진행하던 중
저녁을 전화로 주문했는데 옆집 아기가 자고 있어서
벨을 누르지 말고 문앞에 두고가라고 주문을 한 상황이기 때문에
지금쯤 배달이 왔어야 하는데? 하며 문앞에 주기적으로 나가보는 상황이고

Asynchronous는 코딩을 하던 중 출출해서
배달의 민족으로 네네치킨을 주문하고(실제로 오늘도 주문했다)
초인종 벨소리가 들리면 그제서야 치킨을 받는 것이다.

 

Synchronous는 작업 자체에서 알림이 오지 않기 때문에
불안하고 주기적으로 확인을 해야 하는 과정이 필요하지만
Asynchronous는 안심하고 코딩하다가 맛있게 먹으면 그만이다.

효율면만 생각하면 무조건 비동기만 사용하는게 맞는 것 같지만
동기적으로 처리되어야만 하는 경우가 있는데
예를 들면 은행 등의 이체 작업을 할 경우 등과
숫자가 들어가는 작업들에서 덧셈 곱셈등의 작업들이 순서가 바뀔 경우
문제가 생길 수 있기 때문에 동기적으로 처리되어야 한다.

또한 동기적 처리는 일련의 흐름이 명확하기 때문에
유지보수 및 디버깅을 하기 쉽다는 장점이 있다.

 

@하지만 Blocking/Non-blocking의 장단점이 아닌 Synchronous의 장점인 이유는 모르겠다.

Synchronous와 Asynchronous의 차이는 확인하는 주체성 여부라고 설명하지만

막상 Synchronous의 장점인 동시처리 등은 사실 Blocking의 장점이 아닐까?

이 부분은 추가적인 학습이 필요해보인다.




(1).백준 6378 디지털 루트는 10보다 큰 숫자인 경우
각 자릿수를 모두 합해 새로운 숫자를 만드는 것을 반복한 다음
최종적으로 나온 숫자를 구하는 문제로
최대 1000자리의 숫자기 때문에 number로 처리가 안된다는 점을 주의해야 했다.
while을 사용해 string 상태의 길이비교로 2가 넘을 경우 반복시켰다.

let input = `24
39
0`.split('\n')

let result = []
for(let i = 0 ; i < input.length-1 ; i++){
    let num = input[i]
    while(num.length >= 2){
        let temp = num
        let sum = 0
        for(let i = 0 ; i < temp.length ; i++){
            sum += Number(temp[i])
        }
        num = String(sum)
    }
    result.push(num)
}
console.log(result.join('\n'))




(2)백준 24954 물약 구매는 하나의 물약을 구매할 경우
다른 물약들의 가격이 할인되는데 어떤 순서로 물약을 구매했을 경우
가장 저렴하게 물약을 살 수 있는지에 대한 문제였다.(가격출력)

처음에는 물약의 범위를 1000까지라고 생각하고
어마어마하게 어려운 문제라고 생각하고 고민했지만 답이 없었다.
이건 어떤 문제 유형인지 힌트를 얻으려고 하단에서 알고리즘 분류를 눌러보니
구현, 브루트포스라는 간단한 태그밖에 존재하지 않았다.

위로 올라가 자세히 보니 1000은 물약의 가짓수가 아닌 가격 범위였고
물약의 가짓수는 겨우 10밖에 되지 않아 안심하고 풀 수 있었다.

예제도 그렇게 단순하지 않지만
실제 적용될 연산은 복잡하기 때문에 
물약의 갯수, 가격, 할인(문자열로 들어와 쪼개줘야 했다), 최저값을 선언하고
물약의 idx를 넣을 경우 구매가격을 출력하는 계산함수를 만든 다음
재귀를 구현해 현재 가능한 idx 수열을 각각 계산함수로 계산한 다음
현재 lower값과 비교해 최저값을 저장하게 구현했다.

도중에 더 적은 값으로 출력되어 문제를 확인해보니
idx는 배열을 다루기 때문에 당연히 0부터 시작해야 하지만
기본적으로 입력되는 데이터는 물약의 순서를 1부터 시작했다.
이를 해결하기 위해 입력받은 idx는 -1처리를 해주니 정상적으로 동작했다.

let input = `4
10 15 20 25
2
3 10
2 20
0
1
4 10
1
1 10`.split('\n')
let arrLength = Number(input[0])
let price = input[1].split(' ').map(Number)
let discount = []
let lower = 10000
for(let i = 2 ; i < input.length ; i++){
    let dcAmount = Number(input[i])
    if(dcAmount === 0){
        discount.push(0)
    }
    else if(dcAmount){
        let dcArr = []
        for(let j = i+1 ; j < i+1+dcAmount ; j++){
            let [dcIdx, dcPrice] = input[j].split(' ').map(Number)
            dcArr.push([dcIdx-1, dcPrice])
        }
        discount.push(dcArr)
    }
}
//계산함수를 구해야 한다
//1~n번쨰 순서를 넣을 경우 각각 숫자대로 처리하는 계산
function calculator(order) {
    let nowPrice = [...price]
    let nowPayed = 0
    
    for(let i = 0 ; i < order.length ; i++){
        nowPayed += nowPrice[order[i]]
        if(discount[order[i]]){
            for(let j = 0 ; j < discount[order[i]].length ; j++){
                let [dcIdx, dcPrice] = discount[order[i]][j]
                nowPrice[dcIdx] = Math.max(1,nowPrice[dcIdx]-dcPrice)
            }
        }
    }
    return nowPayed
}

//2~10개의 물약 순서 섞어줄 재귀
function recurtion(arr){
    if(arr.length === arrLength){
        lower = Math.min(calculator(arr),lower)
        return
    }
    for(let i = 0 ; i < arrLength ; i++){
        if(arr.includes(i) === false){
            recurtion([...arr,i])
        }
    }
}
recurtion([])
console.log(lower)

'회고' 카테고리의 다른 글

[취업준비일지] - 69  (0) 2022.12.28
[취업준비일지] - 68  (0) 2022.12.27
[취업준비일지] - 66  (0) 2022.12.25
[취업준비일지] - 65  (0) 2022.12.24
[취업준비일지] - 64 - 원티드 인턴십 4일차  (0) 2022.12.23

+ Recent posts