전체 글115 [KMP] Kotest로 알아본 Stub vs Fake (테스트 더블) 📚 책의 가장 마지막 장인 12장에서는 "코루틴 단위 테스트"에 대해 다룬다.이때 테스트 더블에 대해 설명해주면서 그 종류 중 하나인 Stub을 들어주었다. 그러나 책을 읽던 당시의 나는 테스트 코드를 처음 접했기에 Stub을 왜 사용하는지 이해가 되지 않았다. 그러다, KMP 프로젝트에서 kotest를 이용해 테스트 코드를 작성할 기회가 있었는데 기존에 사용한 Mockk 라이브러리는 멀티플랫폼에서 사용이 불가하기에 Stub으로 구현해야만 했었다. 이 과정 덕분에 Stub이 무엇인지 이해가 되었고 그 과정을 설명해보려 한다. 테스트 더블우선 테스트 더블에 대해 먼저 알아보자.테스트 더블이란, 다른 객체와 의존성을 가진 객체를 테스트하기 위해 사용하는 것으로 "객체에 대한 대체물"을 의미한다.위 그림처.. 2025. 3. 22. [객사오] 코드로 알아보는 객체의 "역할, 책임, 협력" 📚객체지향의 사실과 오해 객체지향 공부를 하기 위해 를 읽기 시작했다.책의 내용을 무작정 정리하기 보다는, 내가 이 책을 읽고 더 공부하고 싶은 부분을 직접 딥다이브 해 볼 생각이다. 이번에 읽은 챕터는 [01. 협력하는 객체들의 공동체]로 객체지향의 본질에 대해 파고든다. 객체지향적으로 잘 짠 코드는 무엇일까?객체는 충분히 '협력적'이어야 한다. 다른 객체의 요청에 충실히 응답하고, 다른 객체에게 적극적으로 도움을 요청할 수 있어야 한다는 것이다. 객체가 충분히 '자율적'이어야 한다. 본인 스스로의 원칙에 따라 어떤 일을 하거나 자기 스스로 통제하여 절제하는 것을 의미한다. '객체의 자율성'에 대해 보충 설명을 하자면, 객체의 내부와 외부를 명확하게 구분하는 것이다.객체의 사적인 부분은 객체 스스로 .. 2025. 3. 16. [백준/1764/Kotlin] 듣보잡 문제문제를 풀 때 시간 복잡도를 생각하고 풀자는 의미에서 이번 포스팅을 하게 되었다. 이 문제는 "듣도 못한 사람"의 리스트와 "보도 못한 사람"의 리스트 중 중복되는 데이터를 사전 순으로 출력하는 문제이다. 트러블 슈팅1) 시간 초과처음에 코드를 작성했을 때 출력은 제대로 되었는데 막상 백준에서 돌려보니 시간 초과 문제가 발생하였다.내가 작성한 코드의 흐름은 아래와 같다.val neverHeard : MutableSet = mutableSetOf()val result : MutableSet = mutableSetOf()repeat(n) { neverHeard.add(bufferedReader.readLine())}repeat(m) { val neverSeen : String = buffere.. 2025. 3. 16. [KMP] Kotest로 테스트 코드 멀티플랫폼에 적용하기 Kotest멀티플랫폼인 KMP에서 테스트코드를 작성하기 위해서는 Kotlin에서 제공하는 테스트 프레임워크인 Kotest를 사용해야 한다. Kotest에는 종류가 여러 가지가 있는데 나는 BehaviorSpec을 선택했다.그 이유는 BehaviorSpec은 아래처럼 given - when - then 형식으로 표현이 가능하여 더 체계적으로 작성할 수 있겠다고 생각했기 때문이다.class UiStateTest : BehaviorSpec({ given("테스트 조건 환경이 주어졌을 때") { ... `when`("테스트 대상 행위가 발생하면") { ... then("의도한 결과가 검증될 것이다.") { ... .. 2025. 3. 9. [백준/11399/Kotlin] ATM 문제이번에 푼 문제는 누적된 합의 최솟값을 구하는 문제이다.각 개인에게 걸린 값의 합이 최소가 되게 하려면 큰 값은 가장 나중에 더해줘야 되기 때문에 오름차순 정렬을 해주고자 했다.이번에는 내가 놓쳤던 부분에 대해서 정리하고자 한다. 트러블 슈팅1) 띄어쓰기 별로 읽기처음에 BufferedReader.readLine()은 라인별로 읽는다고 생각해서 나는 띄어쓰기 별로 읽어야 하므로 BufferedReader.read()를 사용했었다. 그러나, read() 함수를 사용하면 한 글자(문자)를 읽어 해당 문자의 ASCII 값을 반환한다고 한다. 그래서 readLine().toInt()로 하되, 공백(" ")을 기준으로 분리(split)를 하고, 이를 다시 list로 반환하게 해줬다.val numberList .. 2025. 3. 6. [백준/2751/Kotlin] 수 정렬하기 2 코딩테스트 공부를 다시 시작하려고 한다.어떤 언어로 공부해야 되나 고민이 됐는데 아무래도 Kotlin으로 손이 가서 쉬운 문제부터 차근차근 시작하고자 했다. 문제 문제는 꽤나 쉬운 편에 속한다.이번에는 코틀린의 간단한 문법들을 알아봐서 나중에 시간을 줄여보고자 한다.문제 풀이1) 입출력 흐름표준 입력(System.in)으로부터 데이터를 읽어오기 위해 BufferedReader를 생성한다.표준 출력(System.out)으로 결과를 내보내기 위해 bufferedWriter를 생성한다.그리고 여러 개의 문자열을 빨리 출력하기 위해 StringBuilder를 사용한다. (append를 이용하면 효율적이기 때문)StringBuilder에 모아둔 내용을 한 번에 bufferedWriter로 써서 출력한다.입출력에 .. 2025. 3. 4. [Android] Baseline Profile로 성능 개선하기 앱 성능을 개선해보고 싶다는 생각이 들어 찾아보던 도중 Baseline Profile이 있어 이를 적용해보고자 했다.Baseline Profile의 의미와 적용 과정에서의 트러블 슈팅을 담았다. Baseline ProfileBaseline Profile을 사용하면 포함된 코드 경로의 해석과 JIT(Just In Time) 컴파일 단계를 피하여 최초 실행 후 코드 실행 속도가 약 30% 향상된다.사용자가 느끼는 이점으로는 앱 시작 시간 최적화, 상호작용으로 인한 버벅거림 줄임, 전반적인 런타임 시간 개선 등이 있다. Baseline Profile을 적용하지 않더라도 플레이스토어에서 Cloud Profile을 사용하기는 한다.다만, Cloud Profile은 업데이트 후 배포되기까지 수 시간에서 수일이 걸리.. 2025. 2. 18. [CS] 기초지식 총 정리 (네트워크, 운영체제, 데이터베이스, 자료구조) 누군가 나에게 개발자 이상형이 있냐고 물었을 때 망설임 없이 'CS 지식을 가지고 있는 사람'이라고 답했다.내가 되고 싶은 이상향이기도 하다. 그래서 이번에는 3년 동안 학교에서 배웠던 CS 지식을 복습겸 스스로 정리해보고 싶어서 글을 쓰게 되었다. (중간중간 내가 재학 당시 공부했던 내용을 추가로 첨부했다.)앞으로 각 주제마다 심화로 더 공부할 예정이다.🔥 I. 네트워크네트워크란, 컴퓨터들이 통신망을 통해 서로 그물처럼 연결돼 있는 것을 의미한다. 📍IP 주소첫 번째로 알아볼 개념은 IP 주소이다.IP 주소는 네트워크에 연결된 각 컴퓨터를 구분하는 유일한 주소를 의미한다.이는 클라이언트가 서버에게 요청을 하고 응답을 받을 때 서로의 위치를 알려주는 역할을 하는 것이다. IP 주소는 4byte로 이루.. 2025. 2. 7. [구글 엔지니어는 이렇게 일한다] 소프트웨어 엔지니어링이란 이제 나도 다수의 프로젝트 경험이 있는 개발자가 되었다. 협업을 하면서 겪은 시행착오들도 많았다.유지보수성 있는 코드를 짜는 법, 내 결정을 다른 파트에게 전달하는 법, 파트 내에서의 소통 법 등등 .. 그래서 거대한 소프트웨어 엔지니어링 기업인 '구글'은 어떤 방식으로 협업을 하기에 이렇게 오랫동안 살아남을 수 있었을지 궁금해졌다.이 책을 통해 현업에서 쓰이는 방식을 흡수하여 나도 한 단계 더 성장하고자 했다. 독서를 하면서 기록하고 싶은 부분을 기록할 예정이다. Part II 문화일찍 실패하고, 빨리 실패하고, 자주 실패하라 (76p) 숨기는 것은 해롭다. 프로젝트가 '초기' 단계라면 불안감에 숨기고 싶어하는 것은 인간의 본성이다. 그러나 위대한 아이디어를 세상으로부터 숨기고 완벽히 다듬어질 때가지 .. 2025. 2. 5. [Android] ProcessPhoenix 오픈소스 뜯어보기 안드로이드에서 앱을 재시작 해야 할 때 ProcessPhoenix를 사용하면 간편하게 프로세스를 종료하고 다시 앱을 실행할 수 있다.나는 이러한 사실만 알고 있었고, 아래처럼 코드를 작성했을 때 문제가 없어 보였다.Handler(Looper.getMainLooper()).post { Toast.makeText(context, TOKEN_EXPIRED_ERROR, Toast.LENGTH_LONG).show() // 토큰 만료 토스트 메세지 ProcessPhoenix.triggerRebirth(context) // 앱 재실행 코드} 위 코드는 토큰 만료 시 사용한 코드인데 정작 토큰이 만료됐을 때 토스트 메세지만 뜨고 IllegalStateException이 발생하며 앱이 비정상 종료가 되어버린 것이.. 2025. 2. 2. [Android] SnackBar 디자인시스템 구현기 (Material 뜯어보기) 지난 포스팅에 있었던 BottomSheet에 이어, SnackBar도 디자인시스템을 구현하면서 공부했던 것을 기록하고자 한다.스낵바도 바텀시트와 동일하게 컴포즈로 작성이 되어 있으며 Material3 라이브러리를 사용하지 않는다. 사실 스낵바 관련 포스팅은 여러 번 올렸었다.📍스와이프 이벤트 처리: https://comyou.tistory.com/130📍LineBreak 속성: https://comyou.tistory.com/131📍단어 단위 개행: https://comyou.tistory.com/136 그래서 이번 글에서는 Material 속성에 기반한 구현방식에 집중해서 작성할 것이다. SnackBarHostStateSnackBarHostState는 스낵바의 상태를 관리하는 클래스이다.Mate.. 2025. 1. 30. [Android] BottomSheet 디자인시스템 구현기 (Material 뜯어보기) BottomSheet를 디자인시스템으로 구현하면서 Material의 동작 방식을 공부했던 것에 대해 기록하고자 한다.해당 디자인시스템은 컴포즈로 작성이 되어 있으며 Material3 라이브러리를 사용하지 않는다. BottomSheetType우선, Maeterial과는 상관 없는 바텀시트의 디자인이다. 내가 만드려는 디자인시스템의 바텀시트 타입은 두 가지였다. 버튼이 한 개 있는 OneButton 타입버튼이 두 개 있는 TwoButton 타입 각 타입에 대한 각 버튼의 텍스트를 무조건 작성해 줘야 되기 때문에 Sealed Class로 묶어 작성했다.sealed class BottomSheetType { data class OneButton( val buttonText: String .. 2025. 1. 29. 이전 1 2 3 4 ··· 10 다음