분류 전체보기 21

PCW(Post Compile Weaving) 적용법 및 테스트

서론메서드 실행 전 후로 로그를 찍는 기능을 개발하고 있다.모든 메서드에 대해서 로그 찍는 코드를 직접 작성하는 것은 매우 비효율적이므로 Aspect를 도입했다.처음에는 Spring AOP 방식을 적용하려고 했지만, Dynamic, CGLIB Proxy 방식 모두 메서드가 실행될 때 새로운 객체를 생성한다는 점에서 메모리 사용량과 성능 측면에서 다른 방식의 필요성을 느꼈다.그래서 컴파일 이후 바이트 코드를 추가하는 방식의 AOP 적용을 결정했다.그 중 PCW를 결정한 이유는 CTW는 소스코드 단계에서 위빙이 적용되기 때문에 Lombok과 충돌 가능성이 매우 높으며, LTW는 설정이 매우 복잡하기 때문이다. 세팅 과정1. LogAspect.java@Aspectpublic class LogAspect { ..

Server/Java 2025.08.15

2초의 인증 시간이 걸리는 로직의 동시 처리 성능 개선(1) - 프로파일링 툴 선정

시리즈 설명해시 알고리즘 은닉화를 위해 의도적으로 인증 과정을 2초로 고정 (실제 해싱 시간은 0.5초)딜레이를 주기 위해 Thread.sleep 메서드를 사용했는데, 초당 1000개의 요청을 보냈을 때 평균 응답시간이 35~40초가 나옴이는 보안과 사용성의 균형이 무너진 것이며 개선이 필요함현재 성능을 분석하고 앞으로 어떻게 최적화해나가야 할지에 대한 시리즈 서론처음에는 초당 1000개 요청에 대해 어떻게 성능을 개선할까만을 고민했었다.그래서 Thread.sleep에 대해 알아보고 논블로킹 방식으로 어떻게 개선하는지, 어떻게 스레드 풀을 튜닝해야 하는지 등을 알아봤다.하지만 이러한 노력은 "그래서 현재 어떻게 동작하는데?"로 귀결되었다.현재 어떤 상태로 동작을 하는지 파악을 할 수 있어야 어느 지점이..

Server/Java 2025.06.18

Argon2id 파라미터 조정을 통한 해싱 지연

해싱 지연을 통해 해커가 브루트포스 공격을 하는 데에 더 많은 비용(시간, 메모리, 하드웨어 등)이 들도록 할 수 있다.해킹을 통해 얻는 이득보다 이 비용이 더 크다고 판단되면 해커는 해킹을 중단할 가능성이 높으므로 해싱 지연은 보안을 높이는 데에 중요하다.예를 들어, MD5의 경우 RTX4090 기준 초당 1500억 회의 연산이 가능하므로 브루트포스 공격에 용이하며 보안에 취약하다. 목표사용자는 2~5초 정도의 응답 시간은 기다릴 수 있다고 인식하므로, 응답 시간은 약 3~4초를 목표로 하며 해싱하는 데에 드는 시간은 0.5~1초로 조정하는 것이 목표이다. 초기 파라미터 테스트 코드@Test@RepeatedTest(10)@DisplayName("Argon2 해시 테스트")public void test..

Server/Security 2025.05.26

Salt Hash를 활용한 패스워드 암호화

유저 패스워드 저장 방식@PostMapping("/join")public String join(User user) { userService.join(user); return "redirect:/";} 패스워드 암호화를 하지 않고 데이터베이스에 그대로 저장했다. 패스워드를 암호화하지 않고 저장하는 것의 문제점1. 해커가 DB서버에 접근해 데이터를 탈취했을 때 사용자 이메일과 패스워드 모두를 알게 된다.➤ 보통의 사용자는 여러 서비스에 동일한 이메일과 패스워드를 사용한다.➤ 즉, DB 서버를 운영하는 서비스뿐만 아니라, 다양한 서비스에 탈취한 계정으로 접속해 악의적인 행위를 할 수 있다. 2. 관리자에 의한 유출DB 서버 접근 권한을 가진 관리자가 계정을 유출시킬 수 있다. 이러한 이유로 ..

Server/Security 2025.05.07

rt.jar, ee.jar

rt.jarrt = runtimeJava9 이전까지 java.lang, java.util, java.io 등 핵심 클래스를 담은 Java SE 제공 필수 라이브러리JRE에 포함되어 있었다. Java9부터 새로운 구조 도입으로 사라지고 별도의 모듈로 분리됨즉, rt.jar는 사라지고 jdk안의 lib/modules 안에 분리되어서 포함됨 modules Java 런타임만 이해할 수 있는 특수한 바이너리 구조 (JRT 포맷)내부에 .class 파일이 포함됨JAR/ZIP보다 더 빠르고 공간 효율적으로 클래스를 저장하고 로드할 수 있음오염을 방지하기 위해 임의 변경, 수정이 불가능함 ee.jar과거 EE API(Servlet, JSP, EJB, JPA 등)가 묶여있는 JAR 파일Jakarta EE 로 전환되면서..

Server/Java 2025.04.27

JAR (Java ARchive) - 개념, 구성 요소, 생성, 라이브러리 활용

JAR (Java ARchive)- 항아리, 병, 보관함- 컴파일된 .class 파일, 리소스(.png, .properties ...), jar metadata 등으로 구성됨- JDK에 포함된 프로그램이 ZIP 압축과 동일한 알고리즘을 사용해 압축 (압축 없이 생성도 가능) ➜ 생성된 JAR를 gzip, Pack200 등의 추가 압축 포맷을 적용해 더 작은 크기로 전송할 수 있음 (Pakc200은 Java 런타임 구조 변화 등으로 인해 JDK11부터 deprecated, JDK14에서 완전히 제거됨) ➜ 보통 3~4배, 최대 9배까지 압축 가능 사용어플리케이션을 묶어서 배포하거나 설치할 수 있도록 함라이브러리 패키징단순 압축(JAR 안에 메인 클래스를 지정하면 java -jar 파일명.jar 로 JA..

Server/Java 2025.04.25

[SwiftUI] MVVM 패턴 간단한 예제 + 다형성

서론MVVM의 핵심은 뷰와 비즈니스 로직을 분리하는 것입니다.SwiftUI에서 뷰와 비즈니스 로직을 엮어버리면 다음과 같은 그림이 됩니다.struct ContentView: View { @State private var count = 1 var body: some View { VStack { Text("count : \(count)") .onTapGesture { /* 비즈니스 로직 */ count += 1 } } }} 이런 코드는 다음과 같은 문제가 있습니다.1. 테스트의 어려움비즈니스 로직"만"을 테스트하..

iOS/SwiftUI 2024.11.14

Delegate Pattern을 왜 썼을까?

이렇게 생긴 버튼들의 집합을 구현하기 위해 ButtonsView라는 클래스를 만들었습니다.그리고 ViewContoller와 Delegate를 통해 데이터를 주고받도록 했습니다.사실 ButtonsView 클래스에서 onTapLike() 와 같은 함수를 두어서 buttonsView.onTapLike() 이런식으로 직접 조작을 할 수도 있었을 것입니다.하지만, 왜 Delegate Pattern을 "굳이" 썼는지 정리해보고자 합니다. 1. 구조VC는 Delegate를 구현하는 방식으로 의존하고, ButtonsView는 Delegate를 선언하고 사용하는 방식으로 의존합니다.ButtonsView 입장에서는 함수들을 "직접 구현"하는 것이 아니라, "위임"하게 됩니다. 그래서 명칭이 Delegate Pattern입..

iOS/UIKit 2024.09.03

[UIKit/Refactoring] 전시 화면 데이터 처리 관련 로직 개선하기

- OverviewPLAIN 앱의 전시화면은 이렇게 생겼습니다. (데이터는 가짜입니다.) * mock data ref더보기https://www.google.com/url?sa=i&url=https%3A%2F%2Ftwitter.com%2FChampionsLeague%2Fstatus%2F1348932678297538561&psig=AOvVaw0c_KgXbB1BnBijOhuVlyaS&ust=1722327969680000&source=images&cd=vfe&opi=89978449&ved=0CBEQjRxqFwoTCIDCmejpy4cDFQAAAAAdAAAAABAEhttps://www.google.com/url?sa=i&url=https%3A%2F%2Fwww.pinterest.com%2Fpin%2Flionel-me..

iOS/Refactoring 2024.08.17

[UIKit/Refactoring] Domain + Presentation + MVVM 아키텍처 개선

기존 아키텍처 및 개선의 필요성domain layer + presentation layer + mvvm 파란색 선: 의존기존 아키텍처는 이런 모습으로 구현되어 있었습니다. 의존성이 내부로 향하는 것이 클린 아키텍처의 핵심이라 하면, 문제는 없었습니다.다만, 개발을 빠르게 하다보니 이것이 지켜지지 않는 문제들이 있었습니다.뷰컨에 모델이 들어간다던지, 네비게이션을 직접 한다던지 등등 SRP를 어기는 코드가 있었습니다.또한, 뷰모델에 많은 로직이 들어가 있었는데 뷰와 관련된 로직이 포함된 뷰모델을 테스트하기 어려운 문제도 있었습니다.따라서, 코드를 리팩토링하고 data layer를 추가해서 테스트 가능한 영역을 구분하기로 결정했습니다.  개선된 아키텍처 개선된 구조의 모습입니다.데이터 흐름은 presentat..

iOS/Refactoring 2024.08.09

WWDC24 - Meet Swift Testing

https://developer.apple.com/videos/play/wwdc2024/10179/ Meet Swift Testing - WWDC24 - Videos - Apple DeveloperIntroducing Swift Testing: a new package for testing your code using Swift. Explore the building blocks of its powerful new API, discover...developer.apple.com * XCode16 부터 지원되는 기능입니다.  Building blocks 파일을 추가할 때 새로 생긴 템플릿이 생긴걸 볼 수 있습니다.  @Test attribute함수가 테스트라는 것을 나타냅니다. 이걸 붙이면 XCode가 테..

iOS/WWDC 2024.08.03

[UIKit/Refactoring] 홈 화면 UX 개선하기 (리사이징, 메모리 캐싱)

- 문제 상황홈 화면에서 스크롤 시, 앱이 버벅인다는(렉이 걸린다는) 이슈를 제보받았습니다.실제로 구동을 해보니, 앱이 버벅이고 있었고 메모리 사용량도 심상치 않았습니다.이 문제는 저도 알고 있는 문제였습니다. 하지만, 매번 시뮬에서 테스트하다보니 "시뮬이라서" 렉이 걸리는구나라고 생각하고 있었습니다.  앱의 홈 화면은 이렇게 생겼습니다. - 메모리 디버그순환참조로 인한 메모리 누수 등 메모리로 인한 문제가 아닐까 생각해 메모리 디버그를 확인했습니다. * 아래 문제 상황 설명은 iPhoneXS 디바이스 기준입니다. 앱을 처음 진입한 이후의 메모리 사용입니다.   스크롤을 딱 한번 했을 때의 메모리 사용입니다.이미지 하나의 크기가 5~10MB인걸 감안했을 때, 뭔가.. 뭔가 비정상적이라고 느꼈습니다.  위..

iOS/Refactoring 2024.07.27

[UIKit/Refactoring] MyPageProfileEditViewModel 코드 개선하기 (2)

이전글 : https://ios-dev-su.tistory.com/13 MyPageProfileEditViewModel 코드 개선하기 (1)기존 코드 수정 전의 기존 코드는 다음과 같습니다.더보기 import UIKitimport Combineimport Alamofireimport Kingfisherfinal class MyPageProfileEditViewModel { // MARK: - Properties private let coordinator: MyPageCoordinator private varios-dev-su.tistory.com 이번 포스팅에서는 코드와 구조도 개선하도록 하겠습니다. - tagFieldChangedFromUser() 함수 개선// 유저의 텍스트필드 입력에 따른 뷰모델 및..

iOS/Refactoring 2024.07.17

[UIKit/Refactoring] MyPageProfileEditViewModel 코드 개선하기 (1)

기존 코드 수정 전의 기존 코드는 다음과 같습니다.더보기 import UIKitimport Combineimport Alamofireimport Kingfisherfinal class MyPageProfileEditViewModel { // MARK: - Properties private let coordinator: MyPageCoordinator private var interactor = MyPageDownloadInteractor() @Published var categoryTagItemSelectCount: Int = 0 var categoryTagItems = [TagItem(tag: "제품 디자이너", isSelected: false), TagItem..

iOS/Refactoring 2024.07.13

[UIKit/Refactoring] MyPageNotificationViewModel 코드 개선하기

1 저는 이런식으로 주석을 달아서, 어느 파트가 눈에 쉽게 보이는지를 구성해왔습니다.근데, 주석은.. 기껏해야 주절주절이기 때문에, 삭제하기로 했습니다.또한, extension으로 구분하는 것도 없앴습니다. 2func readNotification(index: Int) { if notifications[index].status == .UnRead { notifications[index].status = .Read putNotificationReadStatus(notificationId: notifications[index].id) }} 알림을 읽지 않은 상태라면 읽음 처리를 하는 함수입니다.들여쓰기를 없앨 수 있어서 없앴습니다.func readNotification(i..

iOS/Refactoring 2024.07.09

클린 아키텍처 - 다형성

(책에 대한 내용을 요약한 것이 아닌, 책을 읽으며 생각을 정리하는 포스팅) 다형성이란? 다형성은 OOP(객체 지향 프로그래밍)의 핵심 개념 중 하나로, 같은 인터페이스나 상위 클래스를 통해 다양한 데이터 타입을 처리할 수 있게 하는 기능이다.다형성은 한 가지 타입이 다양한 동작을 수행할 수 있는 능력이다. 예시 class Game { func play() { print("무슨 게임인지 모르겠지만 일단 시작하겠습니다.") }}class LOL: Game { override func play() { super.play() print("LOL 시작") }}class MapleStory: Game { override func play() { ..

Book/IT 2024.07.05

클린 아키텍처 - 이해관계자, 행위, 구조

모든 소프트웨어 시스템은 이해관계자에게 서로 다른 두 가지 가치를 제공하는데, 행위(behavior)와 구조(structure)가 바로 그것이다.  여기서 이야기하는 이해관계자, 행위, 구조란 무엇일까?책의 문맥을 보고, GPT를 활용하고 뇌피셜을 적어본다. 이해관계자 뒷 내용에 '프로그래머는 이해관계자가 기능 명세서나 요구사항 문서를 구체화할 수 있도록 ...' 이라는 내용이 있는 걸 봐서는 이해관계자라는 표현은 소프트웨어 시스템과 관련된 "모든 사람"이 아니라, 개발자보다 윗 단에서 개발을 지시하는 사람(매니저, CTO, 리더 등)임을 짐작할 수 있다. 행위 사용자가 로그인UI에서 올바른 방식으로 로그인하고, 데이터를 보고, 쓰는 것이다.즉, 행위는 기능 명세를 구현하고 버그를 수정하는 것이다. 구조..

Book/IT 2024.07.04

[UIKit/Refactoring] CollectionView Dynamic Header 개선하기 (SupplementaryView)

기존 구현된 헤더뷰 기존 구현한 헤더뷰의 모습입니다.스크롤이 위에 있을 때는 큰 헤더뷰를 보이다가, 스크롤을 내리면 헤더뷰를 고정하고 상단바처럼 동작하게 했습니다.  개선 목표1) 헤더뷰 변경 위치 정확하게 구하기사용자의 태그가 있을 때랑 없을 때 헤더뷰의 크기가 다릅니다.이는 정확히 언제 헤더뷰가 고정상태로 변경되어야 하는지에 대한 정보가 가변적이라는 것을 의미합니다.기존의 방식은, 특정 높이(고정값) 만큼 스크롤을 했을 때 헤더뷰의 상태를 바꾸는 방식으로 구현했는데, 이를 새로운 방식을 사용하거나 기존 방식을 수정해서 "가변적인 헤더 상태 변경 위치"를 정확히 잡는 것이 목표입니다. 위에 gif를 보면, 헤더뷰 상태가 변경될 때 셀들과 헤더 사이의 간격이 생기는 문제가 있습니다.상태 변경 높이가 잘못..

iOS/Refactoring 2024.06.29