Java
-
[Java] 백그라운드에서 빌드 파일 실행하기 (nohup, &)2022.12.05
[Java] 백그라운드에서 빌드 파일 실행하기 (nohup, &)
일반적으로 터미널에서 어플리케이션을 실행하는 방법은 아래와 같다.
java -jar build/libs/{Project Name}-0.0.1-SNAPSHOT.jar
백그라운드에서 터미널을 종료해도 어플리케이션의 실행 상태를 유지하기 위해서는 아래와 같이 실행하면 된다.
nohup java -jar build/libs/{Project Name}-0.0.1-SNAPSHOT.jar &
- nohup은 no hang up의 약자로 '끊지마'라는 뜻을 가지고 있다.
- &는 어플리케이션이 백그라운드에서 돌아갈 수 있도록 하는 명령어이다.
백그라운드 프로그램의 로그를 확인하고 싶은 경우에는 아래와 같이 실행하면 된다.
tail -f nohup.out
Ctrl + C를 사용하여 로그 보기를 종료할 수 있다.
백그라운드 어플리케이션의 실행을 종료하는 방법은 아래와 같다.
1. 해당 포트에서 동작하고 있는 프로세스 ID (PID) 확인
lsof -i :8080
2. 해당 프로세스 종료
kill -9 {PID}
'Java' 카테고리의 다른 글
[Java] 깊은 복사와 얕은 복사 (Deep Copy & Shallow Copy) (0) | 2022.09.29 |
---|---|
[Java] Stream Sorted(Comparator.reverseOrder()) 오류 (0) | 2022.09.27 |
[Java] 깊은 복사와 얕은 복사 (Deep Copy & Shallow Copy)
오늘도 알고리즘 문제를 풀다가 문제가 생겼다(?)
중복순열 가위바위보 문제를 구글링을 통해 순열 구현을 복사하고 이해하며 푸는 도중에...
위와 같은 끔찍한 광경을 보았다..
여튼 해당 문제가 발생한 이유는 값을 저장하는 배열이 얕은 복사가 되었기 때문이다.
문제가 발생한 코드는 아래와 같은데 해당 코드에서 잘못된 부분을 먼저 찾아봐도 좋을 것 같다.
// 순열에 필요한 정보 : 출력할 result, 가위바위보 배열, result에 저장할 배열, depth, round
public ArrayList<String[]> permutation(ArrayList<String[]> result,
String[] arr, String[] out, int depth, int rounds) {
// 탈출 조건 (Base case)
// 저장한 배열이 rounds 까지 꽉차게 되면 result에 값을 저장하고 result를 리턴한다.
if(depth == rounds) {
result.add(out);
return result;
}
// 반복문을 통해 arr 배열을 순회하면서 값을 입력한다
for(int i = 0; i < arr.length; i++) {
// out의 depth의 index에 rock, paper, scissors를 입력한다.
out[depth] = arr[i];
// 첫번째 index를 입력한 뒤 2번째 index를 입력하기 위해 depth+1을 하여 재귀 호출한다.
permutation(result, arr, out, depth + 1, rounds);
}
return result;
}
...
위에서 문제가 된 부분은
if(depth == rounds) {
result.add(out);
return result;
}
해당 부분이다
result 리스트에 out 배열을 add 할 때 얕은 복사가 일어나면서
out 배열이 변경되는 것과 동시에 result 리스트에 add했던 모든 값들이 변경된 것이다.
❓ 그래서 얕은 복사 / 깊은 복사가 뭔데?
얕은 복사란 실제 값이 아닌 객체의 주소 값을 복사해오는 것이다.
예를 들어 @5fa7e7ff라는 주소 값을 참조하는 객체 A가 있는데
B라는 객체에서 얕은 복사를 하게 되면 B도 @5fa7e7ff라는 주소 값을 참조하는 것이다.
위에서 했던 말을 다시 하자면,
같은 메모리 주소를 참조하기 때문에 실제 out의 값을 변경시키면 참조하고 있던 객체들의 값도 모두 변하게 된다.
반대로 깊은 복사는 실제 값을 새로운 메모리 공간에 복사하는 것이며,
위와 같은 상황에서 @5fa7e7ff의 주소 값을 참조하는 객체 A가 있는데
B라는 객체에서 깊은 복사를 하게 되면,
B는 실제 값을 @2d38eb89과 같은 새로운 메모리에 저장하게 된다.
조금 더 자세히 들어가지만 간단하게 덧붙이자면
위의 그림에서 노란색은 Stack 영역, 아래 파란색은 Heap 영역이라고 할 수 있고,
Stack 영역에서 객체 A, B가 각각 Heap 메모리의 실제 값을 참조하고 있는 것이라고 볼 수 있다.
❓ 아니 그래서 어떻게 해결하는데?
if(depth == rounds) {
String[] fullArr = Arrays.copyOf(out, out.length);
result.add(fullArr);
return result;
}
간단하게 정답 먼저 공개하면 위와 같다.
out 배열을 직접 리스트에 삽입하는 것이 아닌
깊은 복사를 통한 새로운 배열을 만들어서 result에 삽입하면 된다.
참고로 깊은 복사를 위한 메서드로는 Object.clone()
, System.arraycopy()
, Arrays.copyOf()
등이 있는데
자세한 정보는 구글링 해보시길 .. ㅎ
'Java' 카테고리의 다른 글
[Java] 백그라운드에서 빌드 파일 실행하기 (nohup, &) (0) | 2022.12.05 |
---|---|
[Java] Stream Sorted(Comparator.reverseOrder()) 오류 (0) | 2022.09.27 |
[Java] Stream Sorted(Comparator.reverseOrder()) 오류
오늘도 어김없이 알고리즘 문제를 풀던 도중 컴파일 에러가 발생했다.
int[] arr = new int[] {90, 10, 30, 50, 20, 100};
// 배열의 제거를 편하게 하기 위해 정렬된 List 생성
List<Integer> list = Arrays.stream(arr)
.sorted()
.boxed()
.collect(Collectors.toList());
▲ 해당 코드는 문제가 없다.
위 코드에서 List를 역순으로 정렬하고자 아래와 같이 코드를 변경했다.
int[] arr = new int[] {90, 10, 30, 50, 20, 100};
// 배열의 제거를 편하게 하기 위해 정렬된 List 생성
List<Integer> list = Arrays.stream(arr)
.sorted(Comparator.reverseOrder())
.boxed()
.collect(Collectors.toList());
▲ Comparator.reverseOrder()에 빨간 밑줄 발생~
뭐가 문제인지도 모르고 한참을 구글링을 하다가 IntelliJ에 떠있는 반환 타입이 눈에 들어왔다.
IntStream
?? Stream<Integer>
?? IntStream에서는 역순 정렬을 못하나??
자바 공식문서 Stream에 살펴보니 sorted()
와 sorted(Comparator<T> c)
가 인터페이스의 메소드로 오버로딩되어 있는 것을 볼 수 있었고,
// sorted -> boxed
List<Integer> list = Arrays.stream(arr)
.sorted()
.boxed()
.collect(Collectors.toList());
// boxed -> sorted
List<Integer> list = Arrays.stream(arr)
.boxed()
.sorted()
.collect(Collectors.toList());
위 코드처럼 서로의 위치를 바꾼 상태에서 cmd + B
를 입력해 코드의 선언부로 각각 이동해보니
위의 IntStream
에서 사용한 sorted()
메소드는 IntStream.java
에서 선언되어 있었고,
IntStream sorted();
아래의 Stream<Integer>
에서 사용한 sorted()
메소드는 Stream.java
에서 선언되어 있었다.
Stream<T> sorted(Comparator<? super T> comparator);
매개 변수를 아무것도 받지 않으니 에러가 날 수 밖에 없었다...
'Java' 카테고리의 다른 글
[Java] 백그라운드에서 빌드 파일 실행하기 (nohup, &) (0) | 2022.12.05 |
---|---|
[Java] 깊은 복사와 얕은 복사 (Deep Copy & Shallow Copy) (0) | 2022.09.29 |