TIL - 26주차 코드

 

1. Stream API, Linux : 230522

1) Stream API : 전체 코드

  • Program.java
package main.java.ex4.stream;

import java.io.IOException;
import java.util.regex.Pattern;
import java.util.stream.IntStream;


public class Program {
    public static void main(String[] args) throws IOException {
        
        ExamRepository repository = new ExamRepository();
        // List<Exam> list = repository.getList(1);
        // list.forEach(System.out::println);

        // ** Stream API 이용! : 파일 읽어서 사용하기 **
        Exam exam = repository.get(1);
        System.out.println(exam);

        int sum = repository.getKorSum();
        System.out.printf("sum is : %d\n", sum);

        // ** Stream API 이용!! : 문자열 쪼개기 **
        String line = "2,3,4,5";
        Pattern
        .compile(",")
        .splitAsStream(line)
        .limit(2)   // 최대 개수 2개
        .forEach(System.out::println);

        // ** Stream API 이용!! : 박싱하는 방법 : Int -> Integer 형식으로 바꾸기! **
        int[] ages1 = {10,23,34,42,12,24};

        IntStream stream1 = IntStream.of(ages1);
        stream1
        .boxed()
        .toList()
        .forEach(System.out::println);  // ages1 배열의 원소를 1줄씩 끊어서 출력!!

        // System.out.println(list);
        // Int, Doutble, LongStream <->  Stream
        
        // 스트림 사용하는 방법 
        // 1. 콜렉션 
        // 2. 배열
        // 3. 파일

        // int[] ages1 = {10,23,34,42,12,24};
        // IntStream stream1 = IntStream.of(ages1);   // 아래의 Stream 부분과 다르다.
        // stream1.average();

        // List<Integer> ages2 = new ArrayList<>();
        // Stream<Integer> stream2 = ages2.stream();
        // Optional<Integer> firstNum = stream2.findFirst();
        
        // // **Optional은 반환값이 없을 수도 있고 있을 수도 있을 때, 사용한다. 
        // // firstNum.isPresent();

        // // 확실히 반환값이 몇개인지 확인하기!
        // long count = stream2.count();

        // // '데이터 분석하기' : lines는 라인 하나 하나가 데이터를 읽어들이게 된다.
        // // map, reduce 함수도 있다.
        // Files
        // .lines(Path.of("res/data.csv"))
        // .toList()  // toList()는 최종 출력 단계이다. forEach문으로 출력(소비) 가능!
        // .forEach(System.out::println);  // 아래의 람다식과 같은 표현식이다.('funtional Expression')
        // // .forEach(line -> {      // 보통, 소비할 때인 테스트에서 사용된다. 
        // //     System.out.println(line);
        // // });



    }
}



  • ExamRepository.java
package main.java.ex4.stream;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Optional;

public class ExamRepository {

    public Exam get(int id){

        Optional<Exam> result = null;

        try {
            result = Files
            .lines(Path.of("res/data.csv"))
            .skip(1)    // 파일의 첫 줄 스킵하기
            .map(Exam::fromCSV)    // map으로 따로 빼서 매핑 사용 가능
            .filter(exam->exam.getId() == id)
            .findFirst();    // findFirst는 첫 필터링되어 1개만
            // .findAny()  // findAny는 필터링의 1개만 랜덤하게 출력 

        } catch (IOException e) {

            e.printStackTrace();
        }

        if(result.isPresent())
            return result.get();

        // .toList();
        return null;
    }
    
    public List<Exam> getList(int page){
        int size = 5;
        int offset = (page-1)*size;

        List<Exam> list = null;

        try {
            list = Files
            .lines(Path.of("res/data.csv"))
            .skip(1)    // 파일의 첫 줄 스킵하기
            .map(Exam::fromCSV)    // map으로 따로 빼서 매핑 사용 가능
            .filter(exam->exam.getKor() == 90)
            .skip(offset)
            .limit(size)
            .toList();
            // .forEach(System.out::println);
            // .line(->{     // map은 형식을 변경하기.
                // String[] tokens = line.split(",");

                // int kor = Integer.parseInt(tokens[0]);
                // int eng = Integer.parseInt(tokens[1]);
                // int math =  Integer.parseInt(tokens[2]);

                // Exam exam = new Exam(kor,eng,math);
                // return exam;
            // })
            

        } catch (IOException e) {

            e.printStackTrace();
        }
        // .toList();
        return list;
    }

	public int getKorSum() {

        try {
            Files
            .lines(Path.of("res/data.csv"))
            .skip(1)    // 파일의 첫 줄 스킵하기
            .map(Exam::fromCSV)    // map으로 따로 빼서 매핑 사용 가능
            .mapToInt(exam->exam.getKor())
            // // .sum()은 기본형식이 아니라서 forEach로 매번 더해서 바꾸거나 Integer형 Stream에서 Int 배열로 변경해줘야 한다.
            // // mapToInt(n->n.intValue())   // 이 식을 아래처럼 하나로 바꿔주자.
            // .map(exam->exam.getKor()) // exam을 kor로 반환해준다!
            // .mapToInt(Integer::intValue) // 기본형을 바꿔준다.
            .sum();
            // .average():

        } catch (IOException e) {
            e.printStackTrace();
        }
        // .toList();
        return 0;
	}
}



  • Exma.java

package main.java.ex4.stream;

public class Exam implements Comparable<Exam> {
   private int id;
   private int kor;
   private int eng;
   private int math;

   public Exam() {
   }

   public Exam(int id, int kor, int eng, int math) {
      this.id = id;
      this.kor = kor;
      this.eng = eng;
      this.math = math;
   }

   public int getId() {
      return id;
   }

   public void setId(int id) {
      this.id = id;
   }

   public int getKor() {
      return kor;
   }

   public void setKor(int kor) {
      this.kor = kor;
   }

   public int getEng() {
      return eng;
   }

   public void setEng(int eng) {
      this.eng = eng;
   }

   public int getMath() {
      return math;
   }

   public void setMath(int math) {
      this.math = math;
   }

   public int total() {
      return kor + eng + math;
   }

   public static Exam fromCSV(String csv){
      String[] tokens = csv.split(",");

      int id = Integer.parseInt(tokens[0]);
      int kor = Integer.parseInt(tokens[1]);
      int eng = Integer.parseInt(tokens[2]);
      int math =  Integer.parseInt(tokens[3]);

      Exam exam = new Exam(id,kor,eng,math);
      return exam;
    }

   @Override
   public String toString() {
      return "Exam [kor=" + kor + ", eng=" + eng + ", math=" + math + ", id=" + id+ "]";
   }

   @Override
   public int compareTo(Exam exam) {
      return this.total() - exam.total();
   }
}


  • data.csv
id,kor,eng,math
1,50,30,50
2,90,80,70
3,100,30,50
4,23,34,45
5,42,34,54
6,100,100,100
7,0,0,0
8,2,3,4

5) reduce :

  • reduce : 내가 원하는 데이터로 추출하는 것
package main.java.ex4.stream;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Optional;
import java.util.OptionalInt;

public class ExamRepository {

    public Exam get(int id){

        Optional<Exam> result = null;

        try {
            result = Files
            .lines(Path.of("res/data.csv"))
            .skip(1)    // 파일의 첫 줄 스킵하기
            .map(Exam::fromCSV)    // map으로 따로 빼서 매핑 사용 가능
            .filter(exam->exam.getId() == id)
            .findFirst();    // findFirst는 첫 필터링되어 1개만
            // .findAny()  // findAny는 필터링의 1개만 랜덤하게 출력 

        } catch (IOException e) {

            e.printStackTrace();
        }

        if(result.isPresent())
            return result.get();

        // .toList();
        return null;
    }
    
    public List<Exam> getList(int page){
        int size = 5;
        int offset = (page-1)*size;

        List<Exam> list = null;

        try {
            list = Files
            .lines(Path.of("res/data.csv"))
            .skip(1)    // 파일의 첫 줄 스킵하기
            .map(Exam::fromCSV)    // map으로 따로 빼서 매핑 사용 가능
            .filter(exam->exam.getKor() == 90)
            .skip(offset)
            .limit(size)
            .toList();
            // .forEach(System.out::println);
            // .line(->{     // map은 형식을 변경하기.
                // String[] tokens = line.split(",");

                // int kor = Integer.parseInt(tokens[0]);
                // int eng = Integer.parseInt(tokens[1]);
                // int math =  Integer.parseInt(tokens[2]);

                // Exam exam = new Exam(kor,eng,math);
                // return exam;
            // })
            

        } catch (IOException e) {

            e.printStackTrace();
        }
        // .toList();
        return list;
    }

	public int getKorSum() {

        OptionalInt result = null;

        try {
            result = Files
            .lines(Path.of("res/data.csv"))
            .skip(1)    // 파일의 첫 줄 스킵하기
            .map(Exam::fromCSV)    // map으로 따로 빼서 매핑 사용 가능
            .mapToInt(exam->exam.getKor())
            .reduce((a,b)-> a+b);   
            // reduce는 집계하는 것이다. a.getKor()에서 getKor()를 빼는 이유 위에서 exam.getKor()가 있어서!! 

            // // .sum()은 기본형식이 아니라서 forEach로 매번 더해서 바꾸거나 Integer형 Stream에서 Int 배열로 변경해줘야 한다.
            // // mapToInt(n->n.intValue())   // 이 식을 아래처럼 하나로 바꿔주자.
            // .map(exam->exam.getKor()) // exam을 kor로 반환해준다!
            // .mapToInt(Integer::intValue) // 기본형을 바꿔준다.
            // .sum();
            // .average():

        } catch (IOException e) {
            e.printStackTrace();
        }
        // .toList();
        return 0;
	}
}




6) 리눅스

  • drwxr-x--- 9 nwelec newlec : 앞의 newlec은 소유자이고 뒤의 newlec은 그룹이다.

  • sudo chmod 757 dragon / : ‘755’ 권한을 ‘757’로 바꾸기(‘755’ 권한은 기존의 dragon 권한이다.) -> 이제는 ‘읽고 쓰고 실행’ 가능한 것!!
    • 이렇게 하면, 나머지 폴더가 other 권한으로 내려간다.
  • ls -l : 디렉토리 내부의 파일 목록 출력하는데 파일의 권한도 확인 할 수 있다.

  • 예전에는 telnet을 사용했지만 요즘에는 telnet을 사용하지 않는다. 대신 SSH(secure shell)를 사용한다.

  • scp : secure copy : 안전하게 복사하기!!



c. 오너 변경하기 !

  • chown 명령어 : change owner

  • sudo chown heon5th:heon5th heon5th -> 이 유저(소유자:그룹)에게 소유권을 넘겨준다.

  • 내가 가진 권한을 남에게 넘겨줄 수도 있다.




d. 소유권 추가하기 ! :

  • add user



e. 파일을 관리하는 방법 :

  • 압축하는 방법

  • 압축한 것을 풀기

  • 패키지 install 하기

    • 이것은 향상된 툴을 사용한다. : 이젠, apt 툴을 사용한다!1



2. Linux, apt, tomcat : 230523

1) 리눅스를 배우는 이유

  • 기본 소프트웨어를 운영할 수 있는 방법이기 떄문이다.


2) 편집기 2가지 방법(추가)

  • 유닉스와 리눅스에서는 텍스트 편집기를 띄우기 보다는 echo "hello" > Hello.txt로 파일을 쓴다.

  • ed 편집기 사용법(순서 : ed -> 파일 내용 입력 -> . -> f 파일명 -> w -> q)

    • red와 ex 편집기는 잘 사용하지 않는다.

ed   // 편집기 이름 
a	// add하기 
public class Hello3{
	public static void main(String[] arg){
	
.
f Hell3.java	// 파일명 저장
Hello3.java

w	// 저장 
65	// '65byte'라는 크기

q	// 끝내기



3) 정렬하는 방법 :

  • awk : ‘어크?’

  • sort -r Hello3.java

  • tac은 파일의 문자열이 역순, sort는 정렬 방식



4) 압축하는 방법 :

  • tar 파일로 압축하기

  • tar -cf all.tar * : 해당 디렉토리의 모든 파일을 .tar 파일 타입으로 압축하기

  • tar -xvf myfile.tar : 해당 파일을 압축 풀기

  • tar -zcf all.tar.gz * : 해당 디렉토리의 모든 파일을 .gz 파일로 압축하기

  • tar -x : 압축을 푸는 명령

  • tar -tvf all.tar.gz : 파일 내부의 목록 보기

    • tar -t : 파일 내부의 목록 보기 기반


5) 리눅스 패키지 관리 도구 :

  • Debian 계열에는 패키지 관리 도구가 있다. : dpkg
    • 패키지로 설치된 모든 것을 볼 수 있다.
  • redHat 계열에는 패키지 관리도구 이다. : rpm

  • 계열마다 패키지들이 자동설치되는 관리 도구들이 있다.

  • 하지만, 이젠 직접 설치 받을 필요가 없다.

  • 우분투가 관리하는 곳인 deb 파일을 apt 툴을 통해 다운 받으면 된다.**



6) 리눅스 패키지 관리 도구 사용하기 :

  • apt 도구에서 패키지 검색하기** : apt-cache search jdk

  • apt 도구에서 패키지 설치하기** : sudo apt-get install openjdk-17-jdk

  • ‘Ubuntu sudo apt get update 404 Not Found problem’ 문제 : sudo apt-get update
    • 업데이트 먼저하고 jdk 패키지 설치하기!
  • apt 도구에서 패키지 삭제하기** : sudo apt-get remove openjdk-17-jdk
    • 하지만 apt 명령어로 패키지가 그냥 지워지지는 않는다. 디렉토리로 일일이 들어가서 지워야 한다.
    • /usr/lib/jvm에 들어가서 jdk,open 등으로 검색해서 지우기
  • 파일을 일일이 지우는 방법!! : sudo dpkg -r openjdk-17-jdk:arm64

  • apt 툴은 패키지 관리 툴은 아니다. 원격으로 다운로드해주는 보조해주는 역할이다.**



7) 리눅스 패키지 관리 도구에서 톰캣 다운 받기 :

  • 톰캣 버전이 9버전까지만 있어서 톰캣 버전 10을 직접 다운받아야 한다.


  • wget 이용** : wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.9/bin/apache-tomcat-10.1.9.tar.gz
    • 웹주소를 받아서 다운로드


  • 압축 풀기 : tar -zxvf apache-tomcat-10.1.9.tar.gz


  • 경로 옮기기!** :
    • ‘heon’ 폴더에서 시작(사용자 고치기)
    • mv download/apache-tomcat-10.1.9 ../setup/
    • ls setup/
    • 굳이 cd를 이용하지 않아도 된다!!


  • 톰캣 실행시키기 : 어디서든 startup.sh 명령어 가능하도록 하는 방법!!


  • ps : 현재 실행 중인 프로세스 목록을


  • whereis java


  • man java : menual 파일
    • ps -e less : 현재 실행 중인 프로세스 목록 검색하기 -> 여기서 파일명이 가장 긴 것이 톰캣 파일이다.

s

  • 톰캣 파일 실행하는 방법 : cd setup/apache-tomcat-10.1.9/bin 이동하여 ./startup.sh 파일을 실행하기!



8) 어디서든 톰캣 파일을 실행할 수 있게 Path 경로 설정하기 :

a. 직접 경로 연결

  • ‘echo $PATH’


b. 링크 파일을 실제 파일로 옮겨 주기


  • jdk 파일 구조 :
    • /usr/bin/java : 여기 있는 jdk는 링크 파일이다.
    • /etc/alternates/java : 여기 있는 jdk는 실제 파일이다.


  • DOS도 프로그래밍 가능한 파일을 갖고 있다. 배치파일이라고 부른다.(DOS Shell Script?)


  • 그래서 bin이라는 폴더가 있으면, 거기에 있는 파일을 내 PATH에 저장


c. sudo 안쓰고 유저에게 권한 넘겨주기!

  • echo “date” > test.sh


  • 실행 권한 넘겨주기 1 :
    • chmod 764 test.sh
    • 기존에는 권한이 554 였다.


  • 실행 권한 넘겨주기 2 :
    • chmod u+x test.sh
    • 유저에게 test.sh 실행 권한 넘겨주기


  • --physical
    • 하드링크를 만든다.
    • 파일에 강한 결합력


  • --symbolic
    • 약한 결합력을 사용
    • --physical와 같이 사용하면, 동기화가 된다.


d. 어디서든 톰캣 실행하기 최종 실습 :

  • 톰캣 실행 : ln -s ~/setup/apache-tomcat-10.1.9/bin/startup.sh ~/bin/startup.sh

  • 톰캣 끄기 : ln -s ~/setup/apache-tomcat-10.1.9/bin/shutdown.sh ~/bin/shutdown.sh




9) 남들과 공유하여 톰캣 파일을 실행할 수 있게 설정하기 :

  • 상위의 개념으로 톰캣 파일을 올리기

  • 기존에는 usr/bin 폴더였다면 usr/sbin으로 톰캣 파일을 해당 디렉토리로 올리기




3. 230524

1) 톰캣 파일을 공유하기

  • 시스템적을 만든 폴더는 ‘usr’ 폴더에 담기

  • 개인적으로 만든 파일들은 ‘opt’ 폴더에 담는다.




2) 리눅스 폴더 및 파일의 권한 정리!

  • 톰캣은 writing 기능까지 있어야 톰캣을 실행시킬 수 있다.


  • 압축이 풀어지는 것과 같이 파일이 만들어 질 떄, 부모의 권한을 받게 된다.
    • ‘newlec’ 폴더에서 풀면 ‘newlec’ 권한을 얻고 root 폴더에서 풀면 root 권한을 얻는다.
    • 하지만, 이게 아니라 생정자에 따라 생성자의 권한을 가져간다. 폴더를 누가 만들었느나에 따라 달라진다!


  • copy(‘cp’)와 move(‘mv’)는 다르다.
    • 폴더를 누가 만들었느나에 따라 달라진다!


  • 윈도우는 다르다. 부모의 폴더와 권한에 따라 정해진다.


  • etc 폴더에 설정 파일들이 모두 있다.


  • sudo adduser dragon : 자기 조원을 하나 추가한다.


  • shadow 비밀번호를 설정하는 폴더이다.



3) 다른 사용자도 권한 넘겨줘서 같은 톰캣을 사용하게 하기

  • 예시 : id가 kim으로 실행!


  • 구글 검색하기**
    • ‘add user to group’ 라고 구글에 검색하기!



a. 리눅스 실행 명령어** :


  • 같은 group에 추가하여 같은 group을 kim으로 실행하기


  • sudo adduser kim : 사용자를 추가할 때


  • sudo usermod -a -G tomcat kim : 사용자를 설정을 변경할 때


  • 위의 명령어를 사용하기 전에 그룹명으로 폴더를 만들거나 ‘adduser’(‘adduser’를 하면 사용자와 폴더를 동시에 만들어 준다.)를 하고 sudo groupadd 그룹명으로 실행하기!


  • sudo chgrp -R tomcat apache-tomcat-10.1.9/
    • ‘chgrp’은 그룹명을 바꿔주는 설정이고
    • ‘R’는 리퀄시브라고 재귀적으로 그 하부의 폴더를 포함해서 재귀적으로 그룹명을 바꿔준다.
    • 원래는 tomcat의 상위폴더에서 해야되지만 이렇게하면 ‘apache-tomcat-10.1.9/’ 이부분이 필요없다. 그렇지만 그대로 tomcat 폴더에서 진행하려면 그 하위 폴더(‘apache-tomcat-10.1.9/’)가 필요하다.**


  • sudo chmod -R u+rw logs/
    • 권한 부여해주기!**


  • 이제 ‘kim’의 사용자 서버를 껐다가 키면 톰캣 서버를 공유하여 사용할 수 있다.**


  • drwxr-xr-x : 권한 순서가 ‘소유자-그룹-other(사용자)’ 순서이다.



b. 권한 추가 :

  • 톰캣을 실행하려고 하면, 아직 권한이 없다. 그래서, 에러가 발생하고 권한을 추가해줘야 한다.
    • /usr/share/tomcat에서 sudo chmod -R g+w apache-tomcat-10.1.9/를 실행하자!


  • 이렇게 하면, 아래 결과처럼 권한이 바뀐다.
heon@heon-server:/usr/share/tomcat$ ls -l
total 4

drwxrwxr-x 9 root tomcat 4096 May 24 06:01 apache-tomcat-10.1.9


  • 그래서 kim 사용자 서버에서 tomcat을 실행시킬 수 있다.
    • 명령어 : /usr/share/tomcat/apache-tomcat-10.1.9/bin/startup.sh



c. 웹주소 공유하기

  • 명령어 1 : sudo apt install w3m

  • 명령어 2 : w3m http://localhost:8080




d. bin 폴더에서 톰캣 실행 파일과 취소 파일 다시 만들기 :

  • 새로 만들어지는 톰캣 파일에는 ‘tomcat-‘를 붙여주자

  • tomcat-startup.sh 실행 파일 만들기의 명령어 1 : sudo ln -s /usr/share/tomcat/apache-tomcat-10.1.9/bin/startup.sh /usr/bin/tomcat-startup.sh


  • tomcat-shutdown.sh 실행 파일 만들기의 명령어 2 : sudo ln -s /usr/share/tomcat/apache-tomcat-10.1.9/bin/shutdown.sh /usr/bin/tomcat-shutdown.sh


  • 톰캣 그룹에 포함되면 같은 파일을 공유해서 다시 만들어진 톰캣 파일을 사용가능하다.



e. 에러 고치기 :

  • 권한 추가가 필요하다.

  • cd webapps로 이동하기 위해서 sudo chmod 755 webapps으로 권한 추가 부여해주기

  • sudo chmod -R 755 webapps 이용

  • sudo chmod -R 755 work 이용




f. 실제 사용 시, 톰캣 파일 스펙

  • 임베디드 톰캣이 아니라



. 실제 사용 시, 톰캣 파일 스펙

  • ctrl + t + z : 리눅스의 nano 편집기에서 백그라운드로 돌아오는 방법

  • jobs : 백그라운드로 오면 작업 중인 일들을 확인 할 수 있다.

  • fg : 아까한 작업으로 다 시 되돌아갈 수 있다.