🔶코딩테스트
🔶AWS
🔶리눅스
≣ 목차
/ 오늘의 TIL /
코딩테스트
기존 코드
import java.util.ArrayDeque;
public class Solution {
/**
* @param s 문자열
* @return 성공 1, 실패 0
*/
public static int solution(String s)
{
ArrayDeque<Character> stack = new ArrayDeque<>();
int lenS = s.length();
char[] chars = new char[lenS];
for (int i = 0; i < lenS; i++) {
//char 형으로 변환한다.
chars[i] = s.charAt(i);
}
//원본 문자열 길이만큼 진행한다.
for (int i = 0; i < lenS; i++) {
//stack이 비어있지 않은 경우만 로직 수행 가능
if (!stack.isEmpty()) {
//stack에서 비교할 대상을 꺼낸다.
char compare = stack.peek();
//동일한 값: pop
if (compare == chars[i]) {
stack.pop();
}
//다른 값: push
else {
stack.push(chars[i]);
}
}
//비어있는 경우는 값을 추가한다.
else {
stack.push(chars[i]);
}
}
return stack.isEmpty() ? 1 : 0;
}
public static void main(String[] args) {
System.out.println(solution("baabaa"));
}
}
리팩토링
s.toCharArray(): String 문자열 -> char 문자열로 변경할 수 있다.
조건문을 적절하게 활용하자 (if - else if - else)
/**
* @param s 문자열
* @return 성공 1, 실패 0
*/
public int solution(String s)
{
ArrayDeque<Character> stack = new ArrayDeque<>();
//원본 문자열 길이만큼 진행한다.
for (char c : s.toCharArray()) {
//stack이 비어있는 경우 값 추가
if (stack.size() == 0) {
stack.push(c);
}
//마지막 대상과 문자가 동일한 경우 값 제거
else if (stack.peek() == c) {
stack.pop();
}
//마지막 대상과 문자가 다른 경우 값 추가
else {
stack.push(c);
}
}
return stack.isEmpty() ? 1 : 0;
}
AWS
인바운드규칙(방화벽): 서버에 접근하는 포트 번호 허용 규칙
0.0.0.0/0 로 설정해두면 누구나 이 페이지에 접근할 수 있다.
터미널로 접속하기
key-pair를 최초로 생성하면 pem key가 생성된다.
보안 설정을 해주어야 접속이 가능하다.
chmod 400 {pem key 경로}
aws에 접속하기
ssh -i {pem key 경로} ec2-user@{IP주소}
AWS 콘솔로 접속하기
(접속 완료. 귀엽다!)
서버 종료
Ctrl + C
리눅스
Ctrl + A: 맨 앞으로 이동
Ctrl + E: 맨 뒤로 이동
파일 내용물 확인
파일 직접 접근
리눅스 편집기 vim 사용
vi nohup.out
터미널에서 내용 확인
#전체 내용 확인
cat nohup.out
#끝 부분만 확인
tail nohup.out
#실시간으로 출력해주는 속성
tail -f nohup.out
명령어
mkdir folder1 #폴더 생성
ls #목록 확인
ls -l #목록 데이터 자세한 정보 확인 (ll)
drwxr-xr-x. 2 ec2-user ec2-user 6 May 31 02:45 folder1
d: 디렉토리 폴더
r: 읽기
w: 쓰기
x: 실행
폴더 소유자의 권한 / 폴더 소유 그룹의 권한 / 아무나 접근했을 때
2: 폴더에 걸려있는 바로가기 개수
ec2-user: 폴더의 주인 이름
ec2-user: 폴더 소유 그룹 이름
6: 폴더(파일)의 크기 - byte
시간: 최종 변경 시간
폴더명
pwd: 현재 경로 확인
rmdir: 디렉토리 폴더 삭제
프로그램 최신 버전으로 업데이트
sudo yum update
sudo: 관리자 권한 실행
yum: 리눅스 패키지 관리 프로그램
update: 현재 설치되어있는 프로그램 최신 버전으로 업데이트
설치
git 설치
sudo yum install git -y
-y: y를 입력하지 않아도 자동으로 설치된다.
java 설치
sudo yum install java-11-amazon-corretto -y
java -version #설치 확인
mysql 설치
wget https://dev.mysql.com/get/mysql80-community-release-el7-5.noarch.rpm
sudo rpm -ivh mysql80-community-release-el7-5.noarch.rpm
sudo yum install mysql-community-server
systemctl: 현재 보이지 않는 프로그램을 관리하는 명령어
sudo systemctl status mysqld
[ec2-user@ip-172-31-42-56 ~]$ sudo systemctl status mysqld
○ mysqld.service - MySQL Server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; preset: disabled)
Active: inactive (dead)
Docs: man:mysqld(8)
http://dev.mysql.com/doc/refman/en/using-systemd.html
status가 inactive인 상태는 정상적으로 설치됐으나 아직 활성화되지 않은 상태이다.
상태를 활성화 시키기 위해서 해당 명령어를 입력한다.
sudo systemctl restart mysqld
[ec2-user@ip-172-31-42-56 ~]$ sudo systemctl status mysqld
● mysqld.service - MySQL Server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; preset: disabled)
Active: active (running) since Fri 2024-05-31 05:59:53 UTC; 8s ago
Docs: man:mysqld(8)
http://dev.mysql.com/doc/refman/en/using-systemd.html
Process: 49069 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
Main PID: 49182 (mysqld)
Status: "Server is operational"
Tasks: 38 (limit: 1114)
Memory: 423.4M
CPU: 6.295s
CGroup: /system.slice/mysqld.service
└─49182 /usr/sbin/mysqld
Mysql8 임시 비밀번호 확인 명령어
sudo cat /var/log/mysqld.log | grep "A temporary password"
임시 비밀번호: A!I4P8j.N&2Y
[ec2-user@ip-172-31-42-56 ~]$ sudo cat /var/log/mysqld.log | grep "A temporary password"
2024-05-31T05:59:48.294125Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: A!I4P8j.N&2Y
해당 임시 비밀번호로 mysql 접속
임시 비밀번호일 경우 ddl이 불가능하다.
mysql -u root -p
비밀번호 변경
8자리 이상, 대문자 소문자 숫자 특수문자 포함 필수
alter user 'root'@'localhost' identified with mysql_native_password by "Abcd1234!";
mysql 종료
exit;
AWS <-> Github 연동 및 배포
git clone https://github.com/kdelay/Server-All-In-One.git
EC2는 메모리가 부족할 수도 있기 때문에, 메모리가 부족한 경우 디스크를 사용하도록 설정한다.
Swap 설정
#스왑 메모리 할당 (128M * 16 = 2GB)
sudo dd if=/dev/zero of=/swapfile bs=128M count=16
#파일 권한 설정
sudo chmod 600 /swapfile
#스왑 파일 생성
sudo mkswap /swapfile
#스왑 파일을 설정할 수 있도록 세팅한다.
sudo swapon /swapfile
#스왑이 할당되었는지 확인
sudo swapon -s
빌드
빌드 후에 build 파일이 생성된다.
build > libs > jar파일로 서버 실행
#gradlew를 사용하기 위해 실행할 수 있도록 설정한다.
chmod +x ./gradlew
#gradle을 이용해 프로젝트를 빌드하고 테스트를 제외하고 빌드한다. (EC2 성능 이슈)
./gradlew build -x test
현재 빌드되어있는 결과물 제거
./gradlew clean
자바 실행
jar파일을 java -jar 명령어로 실행시킨다.
intelliJ에서 설정해둔 profile을 --spring.profiles.active=dev 속성을 통해 설정한다.
java -jar build/libs/library-app-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev
백그라운드로 실행하기
#nohup [명령어] &
nohup java -jar build/libs/library-app-0.0.1-SNAPSHOT.jar &
백그라운드로 실행하고 나면 백그라운드로 실행되고 있는 프로그램의 log가 저장되는 nohup.out 파일이 생긴다.
[ec2-user@ip-172-31-42-56 Server-All-In-One]$ nohup java -jar build/libs/library-app-0.0.1-SNAPSHOT.jar &
[1] 50946
[ec2-user@ip-172-31-42-56 Server-All-In-One]$ nohup: ignoring input and appending output to 'nohup.out'
[ec2-user@ip-172-31-42-56 Server-All-In-One]$ ls
HELP.md build build.gradle gradle gradlew gradlew.bat nohup.out settings.gradle src
파일 제거
rm nohup.out
상위 폴더에서 백그라운드로 실행
nohup java -jar Server-All-In-One/build/libs/library-app-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev &
백그라운드 서버 종료
작업관리자 명령어
ps aux: 현재 실행중인 프로그램 목록을 확인할 수 있다.
java가 들어가는 프로그램을 확인한다.
ec2-user 50946 4.7 19.5 2539320 190444 pts/1 Sl 06:54 0:13 java -jar build/libs/library-app-0.0.1-SNAPSHOT.jar
ps aux | grep java
백그라운드 서버 종료
kill -9 [프로그램번호]
[1]+ Killed nohup java -jar build/libs/library-app-0.0.1-SNAPSHOT.jar
kill -9 50946
기타
gradle 버전 업그레이드
2.x -> 3.x migration build tool 의존성 제공
runtimeOnly 'org.springframework.boot:spring-boot-properties-migrator'
lombok 의존성 추가
implementation 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
JPA의 한계
대용량 데이터를 처리할 때 성능이 매우 떨어진다.
예를 들어, 사과 데이터 1000개를 insert하는 query를 보내고 싶은 경우 JPA의 saveAll 메서드를 사용하면 사과를 하나씩 전달한다.
query를 1000번 동작하는 불상사가 발생한다...
JPA는 사과 1000개를 모아서 한 번에 전송하는 방법이 없기 때문에 JdbcTemplate의 batchUpdate를 사용해야 한다.
//1만 개씩 잘라서 저장
public void saveAllBatch(List<Fruit> fruits) {
for (List<Fruit> chunk : chunks(fruits, 10_000)) {
jdbcTemplate.batchUpdate("insert into fruilt (name, price) values (?, ?)", new BatchPreparedStatementSetter()) {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
ps.setString(1, chunk.get(i).getName());
ps.setInt(2, chunk.get(i).getPrice());
}
@Override
public int getBatchSize() { return chunk.size(); }
}
}
}
//10만건 -> [1만건] / [1만건] / ...
private static List<List<Fruit>> chunks(List<Fruit> inputs, int chunkSzie) {
List<List<Fruit>> result = new ArrayList<>();
int size = inputs.size();
int currStep = 0;
while (currStep + chunkSize < size) {
result.add(new ArrayList<>(inputs.subList*currStep, currStep + chunkSize)));
currStep += chunkSize;
}
result.add(new ArrayList<>(inputs.subList(currStep, size)));
return result;
}
application.yml 파일에서 추가 설정 필요
datasource.url="~~?rewriteBatchedStatements=true"
'Blog > TIL' 카테고리의 다른 글
[240602] JPA 영속성 컨텍스트 (0) | 2024.06.02 |
---|---|
[240601] 코딩 테스트 문제 풀기 (0) | 2024.06.01 |
[240530] 도메인 연관 관계의 중요성 (0) | 2024.05.30 |
[240529] 직접 해봐야 안다 (0) | 2024.05.29 |
[240528] 백문이 불여일타! (0) | 2024.05.28 |
댓글