Today I Learned

최지웅·2024년 7월 15일
0

Today I Learned

목록 보기
178/238
post-thumbnail

오늘 할일
1. 리눅스 서버 구축 1일차
2. LeetCode
3. 독서
4. 도커 1일차

오늘 한일

1. 리눅스 서버 구축 시도

  • "리눅스를 활용한 회사 인프라 구축의 모든것"을 따라 진행한다.
    1-1. Putty 설치
$ 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를 추가로 설정해줘야 한다.

2. 도커 1일차_ 갑자기 끌려서 도커 교과서라는 교재를 기반으로 진행.

일반적인 모놀리식 설계보다는 마이크로 서비스 아키텍쳐 설계 기법에 용이하다. 단위로 컨테이너를 사용하며, 새로운 기능 추가 시 별도의 컨테이너로 분리하여 추가한뒤 라우팅 컴포넌트가 외부 요청 시 분배해준다.

도커는 MSA, 모놀리식 모두 클라우드로 이주하는데에 유용하다. 어찌보면 위의 독자적인 인프라 설계와는 반대되는 기술 스택이다.

매 챕터별로 아래의 명령어로 초기화를 진행한다.

$ docker container rm -f $(docker container ls -aq)
$ docker image rm -f $(docker image ls -f reference='diamol\*' -q)

3. LeetCode

    1. Reorder Routes to Make All Paths Lead to the City Zero 에서 지난번에 TLE가 발생하였는데, 변경된 코드에서 최적화를 진행해보겠다.
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;
    }
}

profile
이제 3학년..

0개의 댓글