TIL #48

loci·2024년 6월 17일
0

TIL

목록 보기
46/111

연속 부분 수열 합의 개수

원형수열에서 나올 수 있는 중복을 제외한 합의 개수를 모두 구해야한다.
시간이 오버되어 다른 풀이를 참고했다.

원형으로 만들기위해 새배열에 주어진 배열을 두번 넣어줬다.
각 부분수열의 합을 구해 중복방지를 위해 set컬렉션에 모두 넣어주고 set의 길이를 리턴해주었다.


나의 풀이

class Solution {
    fun solution(elements: IntArray): Int {
        var answer: Int = 0
        var set = mutableSetOf<Int>()
        var mElements = elements + elements
        
        for(i in 1..elements.size){
            for(j in 0..elements.size){
                set.add(mElements.copyOfRange(j, j+i).sum())
            }
        }
        
        return set.size
    }
}

i를 이용해 연속부분수열의 길이를 조절한다.
mElements.copyOfRange(j, j+i).sum()은 배열에서 j ~ j+i 범위의 요소들을 새배열로 만들어 모든 요소를 더한다.


다른사람의 풀이

class Solution {
     fun solution(elements: IntArray): Int {
        val doubling = elements+elements
        val result = HashSet<Int>()
        for (i in 1..elements.size) {
            result.addAll((elements.indices).map {
                doubling.slice(it until it + i).sum()
            })
        }
        return result.size
    }
}

Synchronout - Blocking (동기)

  • 각 작업을 요청하고 응답을 기다림
  • 작업의 실행순서와 완료순서가 같음

Asynchronous - Non-Blocking (비동기)

  • 각 작업을 요청하고 바로 다른 일을 시작
  • 실행순서와 완료순서가 다를 수 있음

쓰레드

작업처리단위는 쓰레드
쓰레드1이 쓰레드2에게 작업을 맡기고 다음작업을 수행 쓰레드1이 쓰레드3에게 작업을 맡기고 다음작업을 수행 하는 방식
효율을 높이려고 나온 방식이지만 지금에선 비효율적인 부분이 있음

  • 쓰레드 생성과 컨텍스트 스위칭의 비용이큼(특히 cpu, 메모리 소모가 많음)
  • Blocking 작업을 수행하면 쓰레드는 대기하면서 자원을 소모함(대기중 작업X)
  • 예외처리 및 취소가 쉽지 않음
  • 쓰레드간 데이터 소통이 어려움
  • 가독성 좋지 않음
fun main( {
	thread(name = "쓰레드 #1"){
		thread(name = "쓰레드 #2"){
			val user = fetchUser()
			println(user)
		}	
		thread(name = "쓰레드 #3"){
			val product = fetchProduct()
			println(product)
		}
	}
})

코루틴

하나의 쓰레드 안에 여러작업단위가 존재

  • 쓰레드보다 훨씬 적은 메모리와 CPU연산을 사용
  • 중단메커니즘을 이용해 쓰레드가 대기하지 않고 계속 일하도록 함
  • 예외처리 및 취소가 쉬움
  • 쓰레드 간에 데이터를 소통하기 쉬움
  • 가독성이 좋음
fun main() = runBlocking{
	launch{
		wait1000ms()
		println("world!")
	}
	println("Hello")
}

suspend fun wait1000ms(){
	delay(1000L)
}

runBlocking

  • Coroutine을 만드는 Coroutine Builder
  • Caller Thread를 코루틴이 끝날때까지 Blocking함
  • Coroutine Scope 밖에서 사용가능
  • main 함수와 같이 특별한 경우에만 씀
    launch
  • Coroutine을 만드는 Coroutine Builder
  • Coroutine Scoope 안에서만 사용 가능
  • Caller Coroutine을 중단하지 않음

suspend fun

  • Coroutine Scope안에서만 사용
  • Caller Coroutine을 중단시키고 자신의 작업을 수행

Coroutine Scope

코루틴의 실행범위를 정의하고 코루틴의 생명주기를 관리한다.

  • GlobalScop : 앱의 생명주기와 함께하는 Scope
  • lifecycleScope : android에서 컴포넌트의 라이프사이클에 해당하는 scope
  • viewModelScope: Android에서 viewModel의 라이프사이클에 해당하는 Scope
  • 커스텀 scope: coroutineScope함수를 이용해 직접 생성

Structured concurrency(구조화된 동기성)을 제공

코루틴은 Scop에 바인딩 되며 부모 Scope이 종료 or 취소되면 자동으로 내부의 모든 코루틴 역시 종료 or 취소됨 (ex. ViewModel이 종료되면 viewModelScope이 종료되고 내부에 사용한 모든 코루틴이 종료됨)

Coroutine Context - 작업정보들의 집합

coroutine Scope에 바인딩 되는 실행 환경 정보
코루틴의 실행에 필요한 정보들 보유 ( Coroutine Name, Job, Dispatcher)

profile
편리한 개발자

0개의 댓글