🔶행렬 곱셈
🔶Comparator
🔶Transaction Exception
≣ 목차
/ 오늘의 TIL /
휴.... 수학 기초때문에 문제를 이해 못할 때가 있는데 알고리즘 문제를 정말 많이 풀어서 공식을 많이 익혀두어야겠다.
행렬 곱셈
\(mn * nk\) 일 때, mk의 행렬을 만들 수 있다.
행렬 곱셈 A[m][n] * B[n][k] -> 새로운 행렬 C[m][k]
https://school.programmers.co.kr/learn/courses/30/lessons/12949
행렬 핵심 로직은 A의 행만큼 반복하는데, 그 내부에 (A의 열 * B의 행) 값을 모두 더한 값이 최종 저장된다.
그래서 j(B의 행) * k(A의 열) 반복이 동작한다.
arr1[i][k] * arr2[k][j]인 이유는
i가 0이고, k랑 j가 반복문을 진행할 때
(00 * 00) + (01 * 10)
(00 * 01) + (01 * 11) 처럼 동작해야 되기 때문이다.
-> [mn * nk]의 동작 원리
-> 동작 원리의 값은 ( 'm'==i, 'n'==k, 'k'==j )라고 생각하면 된다....
k가 먼저 다 돌고(arr1의 열 이동), j값이 증가(arr2의 열 이동)하면서 최종 값을 저장한다.
삼중 for문을 머릿속으로 계산하려니 복잡해져서..ㅠ 구조를 미리 이해해두면 도움될 것이다.
/**
* 행렬 곱셈 A[m][n] * B[n][k] -> 새로운 행렬 C[m][k]
* arr1, arr2의 각 행렬 길이를 구한다.
* 값을 저장할 새로운 행렬을 만든다.
* arr1 열 길이만큼 * arr2 행 길이만큼 반복하고, 각 수를 곱한 후 더한다.
*/
class Solution {
public int[][] solution(int[][] arr1, int[][] arr2) {
int r1 = arr1.length;
int c1 = arr1[0].length;
int r2 = arr2.length;
int c2 = arr2[0].length;
int[][] arr3 = new int[r1][c2];
for (int i=0; i<r1; i++) {
//행렬 핵심 로직
for (int j=0; j<c2; j++) {
for (int k=0; k<c1; k++) {
arr3[i][j] += arr1[i][k] * arr2[k][j];
}
}
}
return arr3;
}
}
Comparator
값을 비교할 때 유용하게 사용되는 Comparator 객체
람다 식으로 적용할 수 있고, 조건문을 추가해서 오름차순/내림차순 정렬이 가능하다.
https://school.programmers.co.kr/learn/courses/30/lessons/120880
stream을 통해 Integer 배열을 만들고 싶은 경우, boxed()로 한 번 감싸서 Integer[]::new 로 변환해준다.
반대로 int 배열을 만들고 싶은 경우, mapToInt + toArray 조합을 사용해서 변환해준다.
값에 대해서 내림차순 정렬할 때는 Integer.compare(b, a);
거리에 대해서 오름차순 정렬할 때는 Integer.compare(ca, cb);
import java.util.Arrays;
import java.util.Comparator;
class Solution {
public int[] solution(int[] numlist, int n) {
Comparator<Integer> comparator = (a, b) -> {
int ca = Math.abs(a - n);
int cb = Math.abs(b - n);
if (ca != cb) { //거리가 동일하지 않은 경우, 거리에 대해서 오름차순 정렬
return Integer.compare(ca, cb);
} else { //거리가 동일한 경우, 값에 대해서 내림차순 정렬
return Integer.compare(b, a);
}
};
//Integer 배열로 변환
Integer[] list = Arrays.stream(numlist).boxed().toArray(Integer[]::new);
//comparator를 이용해서 정렬
Arrays.sort(list, comparator);
//int 배열로 변환
numlist = Arrays.stream(list).mapToInt(Integer::intValue).toArray();
return numlist;
}
}
Transaction
Transaction Exception (예외)
- Checked Exception(Exception 등): commit
-> rollback하고 싶은 경우, @Transactional에 rollbackFor 속성을 적용해주어야 한다.
- UnChecked Exception(RuntimeException 등): rollback
비즈니스 예외는 체크 예외로 만들어야 한다.
예시: 사용자가 상품 주문 후 결제하려고 할 때 결제 exception이 동작했는데, rollback될 경우 주문 내용이 모두 날아간다.
예외를 리턴 값처럼 사용할 수 있다.
checked Exception, xxxException일 때 xxx처리하기 (commit 진행)
Transaction Propagation (전파)
큰 물리 트랜잭션 내부에 외부 논리 트랜잭션, 내부 논리 트랜잭션이 있는데
논리 트랜잭션이 하나라도 롤백되면 물리 트랜잭션 전체 다 롤백된다. (같은 커넥션 사용하는 경우)
-> rollback-only가 설정된다. UnexpectedRollbackException 발생!
물리 트랜잭션(최상위 트랜잭션)이 커밋하는 것이 실제로 커밋을 발생시킨다.
별도의 물리 트랜잭션을 가지고 싶은 경우(DB 커넥션 따로) REQUIRES_NEW 옵션을 사용한다.
기존 커넥션에 함께하는 것이 아니라, 신규 커넥션을 사용하기 때문에 성능 이슈를 고려해야 한다.
DefaultTransactionAttribute definition = new DefaultTransactionAttribute();
definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
'Blog > TIL' 카테고리의 다른 글
[240527] 코딩테스트 다다익선 (0) | 2024.05.27 |
---|---|
[240526] API 개발하기 (0) | 2024.05.26 |
[240523] 배워도 배워도 끝이 없네 (0) | 2024.05.23 |
[240522] 드디어 JPA를 접하다 (0) | 2024.05.22 |
[240521] JdbcTemplate 파헤쳐보기 (0) | 2024.05.21 |
댓글