오늘 할일
1. 리눅스 서버 구축 1일차
2. LeetCode
3. 독서
4. 도커 1일차
오늘 한일
$ wget https://the.earth.li/~sgtatham/putty/latest/putty-0.81.tar.gz
$ tar -xvf putty-0.81.tar.gz
$ cd putty-0.81/
$ sudo yum install make
$ sudo yum update
$ gcc #gcc 꾸러미 설치
$ ls /usr/sec/kernels # 비어있다 ( https://boring-notes.tistory.com/entry/CentOS-make-%EC%BB%B4%ED%8C%8C%EC%9D%BC-%EC%8B%9C-%EC%98%A4%EB%A5%98%EA%B7%B8%EB%9F%B0-%ED%8C%8C%EC%9D%BC%EC%9D%B4%EB%82%98-%EB%94%94%EB%A0%89%ED%84%B0%EB%A6%AC%EA%B0%80-%EC%97%86%EC%8A%B5%EB%8B%88%EB%8B%A4 )
$ sudo yum install kernel-devel
$ sudo yum install kernel-headers
$ sudo make && sudo make install
여전히 make가 진행되지 않음을 확인할 수 있었다.
cd ./configure안에서 make를 진행해야하는데, ls -a 결과 ./configure 파일이 존재하지 않는다.
이 때 해결방법은 크게 두가지가 있는 듯 하다. ./configure파일이 있는 다른 파일을 다운받거나 yum을 이용해 그냥 다운받는 것. 하지만 이전에 yum install putty시 찾을 수 없다고 떠서 직접 tar.gz를 다운받은 것이었다. 패키지 이름을 재차 확인해 본 후 만약 yum으로 그냥 다운받기 어렵다고 판단되면, autoscan을 이용해서 직접 ./configure를 만들어보겠다. ( https://jybaek.tistory.com/370 )
추가로 검색해보니, putty를 host centos에 설치할 필요가 없어보인다. windows에서 설치 후 centos에 바로 접근시도해보겠다.
$ rm -rf putty*
$ hostname -I
1-2. 중요 명령어와 유틸리티
$ alias vi='vim'
$ unalias vi
$ mkdir -p /var/www/example.com/{content, logs, uploads} # -p 옵션은 부모디렉이 없으면 생성
$ for i in {1..10..2}; do echo "Hello $i"; done
$ PATH=$PATH:/usr/local/bin
$ export
$ export PATH=$PATH:/usr/local/bin #또 다른 방법
Ctrl+a는 맨 앞줄로 이동
Ctrl+r은 Reverse-i-search모드로 history에 있는 명령어중 현재 입력되는 명령에 해당하는 것들을 보여준다
$ #설정파일 처리순서
로그인 시 /etc/bashrc 설정을 읽고, ~/.bashrc와 ~/.bash_profile을 읽는다.
로그아웃 시 ~/.bash_logout과 /etc/bach.bash_logout을 처리한다.
보통 ~/.bash_profile에 개인적인 내용을 설정한다.
설정파일 변경 시 source ~/.bash_profile이나 ~/.bash_profile로 설정파일을 읽어야 현재 bash에 반영된다.
$ export VISUAL=/usr/bin/vim
$ export PS1=[\u@\h \W]$
위의 내용을 참고하여 직접 전체디렉토리를 표시하게끔 하는 설정을 ~/.bash_profile에 설정해보자.
$ vim ~./bash_profile
$ PS1='[\u@\h \[\e[31m\]\w\[\e[m\]]\$ ' #추가
$ qw
마지막으로, 프로그램 설치 시 생긴 DLL이 /lib, /usr/lib, /usr/local/lib같은 일반적인 경로가 아닌 경우 LD_LIBRARY_PATH를 추가로 설정해줘야 한다.
일반적인 모놀리식 설계보다는 마이크로 서비스 아키텍쳐 설계 기법에 용이하다. 단위로 컨테이너를 사용하며, 새로운 기능 추가 시 별도의 컨테이너로 분리하여 추가한뒤 라우팅 컴포넌트가 외부 요청 시 분배해준다.
도커는 MSA, 모놀리식 모두 클라우드로 이주하는데에 유용하다. 어찌보면 위의 독자적인 인프라 설계와는 반대되는 기술 스택이다.
매 챕터별로 아래의 명령어로 초기화를 진행한다.
$ docker container rm -f $(docker container ls -aq)
$ docker image rm -f $(docker image ls -f reference='diamol\*' -q)
public int minReorder(int n, int[][] connections) {//n은 노드의 개수, connections는 a->b방향관계
//connections를 List형태로 순서를 유지하며 저장한다.
List<Integer> queue=Arrays.stream(connections)
.flatMapToInt(IntStream::of)
.boxed()
.collect(Collectors.toList());
//DFS를 위해 도시(0)이 위치하는 인덱스 정보를 큐에 넣어 준비를 한다.(초기값 세팅)
int result=0;
Queue<Integer> indexes=new LinkedList<>();//접근할 인덱스의 목록
for(int i=0; i<queue.size(); i++)
if(queue.get(i)==0)
indexes.add(i);
//0부터 시작해서 DFS진행
int index, target_index, target_val, i;
while(!indexes.isEmpty()){
index=indexes.remove();
if(index%2==0) {//짝수라면 시작지점
result++;
target_index=index+1;
} else{//홀수라면 도착지점
target_index=index-1;
}
target_val=queue.get(target_index);
queue.set(target_index, -1);//현재 index와 같이 처리한 쌍의 데이터 무시를 위함
for(i=0; i<queue.size(); i++){
if(queue.get(i)==target_val){
indexes.add(i);
}
}
}
return result;
}
여전히 71/76 testcase에서 TLE가 발생한다. DFS를 위해 0이 위치하는 인덱스를 큐에 넣는 작업인 2단계를 초기 Queue세팅 단계에 넣어서 추가적인 최적화를 진행해보겠다.
class Solution {
public int minReorder(int n, int[][] connections) {//n은 노드의 개수, connections는 a->b방향관계
int result=0, idx=0;
int index, target_index, target_val, i;
Queue<Integer> indexes=new LinkedList<>();//접근할 인덱스의 목록
//connections를 List형태로 순서를 유지하며 저장한다.
List<Integer> list=new ArrayList<>();
for(int[] conn: connections){
list.add(conn[0]);
if(conn[0]==0)
indexes.add(idx);
idx++;
list.add(conn[1]);
if(conn[1]==0)
indexes.add(idx);
idx++;
}
//0부터 시작해서 DFS진행
while(!indexes.isEmpty()){
index=indexes.remove();
if(index%2==0) {//짝수라면 시작지점
result++;
target_index=index+1;
} else{//홀수라면 도착지점
target_index=index-1;
}
target_val=list.get(target_index);
list.set(target_index, -1);//현재 index와 같이 처리한 쌍의 데이터 무시를 위함
for(i=0; i<list.size(); i++){
if(list.get(i)==target_val){
indexes.add(i);
}
}
}
return result;
}
}
그래도 여전히 TLE가 발생한다. DFS진행부를 최적화해보겠다. 모든 Array를 배열로 바꾸었지만, TLE가 여전히 발생하였다.
class Solution {
public int minReorder(int n, int[][] connections) {//n은 노드의 개수, connections는 a->b방향관계
int result=0, idx=-1, end=0, start=0;
int index, target_index, target_val, i;
int[] indexes=new int[connections.length*2];
int[] list=new int[connections.length*2];
for(int[] conn: connections){
list[++idx]=conn[0];
if(conn[0]==0)
indexes[end++]=idx;
list[++idx]=conn[1];
if(conn[1]==0)
indexes[end++]=idx;
}
//0부터 시작해서 DFS진행
while(start<end){
index=indexes[start++];
if(index%2==0) {//짝수라면 시작지점
result++;
target_index=index+1;
} else{//홀수라면 도착지점
target_index=index-1;
}
target_val=list[target_index];
list[target_index]=-1;//현재 index와 같이 처리한 쌍의 데이터 무시를 위함
for(i=0; i<list.length; i++)
if(list[i]==target_val)
indexes[end++]=i;
}
return result;
}
}