해당 글은 MacOS M1 기반으로 MySQL, Workbench 설치하는 과정을 간략하게 작성했습니다.
brew install mysql
➜ ~ brew install mysql
==> Downloading https://formulae.brew.sh/api/formula.jws.json
#=#=#
==> Downloading https://formulae.brew.sh/api/cask.jws.json
#=#=#
==> Fetching dependencies for mysql: icu4c, ca-certificates, openssl@1.1, libevent, libcbor, libfido2, lz4, protobuf@21, zlib, xz and zstd
==> Fetching icu4c
==> Downloading https://ghcr.io/v2/homebrew/core/icu4c/manifests/72.1
######################################################################### 100.0%
// ... 중간 생략
==> Downloading https://ghcr.io/v2/homebrew/core/zstd/blobs/sha256:e3cb579108afe
==> Downloading from https://pkg-containers.githubusercontent.com/ghcr1/blobs/sh
######################################################################### 100.0%
==> Fetching mysql
==> Downloading https://ghcr.io/v2/homebrew/core/mysql/manifests/8.0.33_1
######################################################################### 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/mysql/blobs/sha256:e56237aaf649
==> Downloading from https://pkg-containers.githubusercontent.com/ghcr1/blobs/sh
######################################################################### 100.0%
==> Installing dependencies for mysql: icu4c, ca-certificates, openssl@1.1, libevent, libcbor, libfido2, lz4, protobuf@21, zlib, xz and zstd
==> Installing mysql dependency: icu4c
==> Pouring icu4c--72.1.arm64_monterey.bottle.tar.gz
🍺 /opt/homebrew/Cellar/icu4c/72.1: 263 files, 78.4MB
==> Installing mysql dependency: ca-certificates
==> Pouring ca-certificates--2023-05-30.arm64_monterey.bottle.tar.gz
==> Regenerating CA certificate bundle from keychain, this may take a while...
🍺 /opt/homebrew/Cellar/ca-certificates/2023-05-30: 3 files, 216.2KB
==> Installing mysql dependency: openssl@1.1
==> Pouring openssl@1.1--1.1.1u.arm64_monterey.bottle.tar.gz
// ... 중간 생략
🍺 /opt/homebrew/Cellar/zstd/1.5.5: 31 files, 2.3MB
==> Installing mysql
==> Pouring mysql--8.0.33_1.arm64_monterey.bottle.tar.gz
==> /opt/homebrew/Cellar/mysql/8.0.33_1/bin/mysqld --initialize-insecure --user=
==> Caveats
We've installed your MySQL database without a root password. To secure it run:
mysql_secure_installation
MySQL is configured to only allow connections from localhost by default
To connect run:
mysql -u root
To start mysql now and restart at login:
brew services start mysql
Or, if you don't want/need a background service you can just run:
/opt/homebrew/opt/mysql/bin/mysqld_safe --datadir=/opt/homebrew/var/mysql
==> Summary
🍺 /opt/homebrew/Cellar/mysql/8.0.33_1: 318 files, 300.0MB
==> Running `brew cleanup mysql`...
Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
==> Upgrading 1 dependent of upgraded formulae:
Disable this behaviour by setting HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
openssl@3 3.1.0 -> 3.1.1
==> Fetching openssl@3
==> Downloading https://ghcr.io/v2/homebrew/core/openssl/3/manifests/3.1.1
######################################################################### 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/openssl/3/blobs/sha256:e2a9c60c
==> Downloading from https://pkg-containers.githubusercontent.com/ghcr1/blobs/sh
######################################################################### 100.0%
==> Upgrading openssl@3
3.1.0 -> 3.1.1
==> Pouring openssl@3--3.1.1.arm64_monterey.bottle.tar.gz
🍺 /opt/homebrew/Cellar/openssl@3/3.1.1: 6,495 files, 28.4MB
==> Running `brew cleanup openssl@3`...
Removing: /opt/homebrew/Cellar/openssl@3/3.1.0... (6,494 files, 28.4MB)
Removing: /Users/junyongmoon/Library/Caches/Homebrew/openssl@3--3.1.0... (7.6MB)
==> Checking for dependents of upgraded formulae...
==> No broken dependents found!
==> Caveats
==> mysql
We've installed your MySQL database without a root password. To secure it run:
mysql_secure_installation
MySQL is configured to only allow connections from localhost by default
To connect run:
mysql -u root
To start mysql now and restart at login:
brew services start mysql
Or, if you don't want/need a background service you can just run:
/opt/homebrew/opt/mysql/bin/mysqld_safe --datadir=/opt/homebrew/var/mysql
mysql --version
➜ ~ mysql --version
mysql Ver 8.0.33 for macos12.6 on arm64 (Homebrew)
mysql.server start
➜ ~ mysql.server start
Starting MySQL
. SUCCESS!
mysql_secure_installation
질문 리스트
``` ➜ ~ mysql_secure_installation
Securing the MySQL server deployment.
Connecting to MySQL using a blank password.
VALIDATE PASSWORD COMPONENT can be used to test passwords and improve security. It checks the strength of password and allows the users to set only those passwords which are secure enough. Would you like to setup VALIDATE PASSWORD component?
Press y|Y for Yes, any other key for No: n Please set the password for root here.
New password:
Re-enter new password: By default, a MySQL installation has an anonymous user, allowing anyone to log into MySQL without having to have a user account created for them. This is intended only for testing, and to make the installation go a bit smoother. You should remove them before moving into a production environment.
Remove anonymous users? (Press y|Y for Yes, any other key for No) : y Success.
/**
* bridge_length : 다리에 올라갈 수 있는 트럭 수
* weight : 다리가 견딜 수 있는 무게
* truck_weights : 트럭 별 무게
*/
import java.util.*;
class Solution {
public int solution(int bridge_length, int weight, int[] truck_weights) {
Queue<Integer> queue = new LinkedList<>();
int sum = 0; // 현재 다리를 건너는 트럭 무게의 합
int time = 0; // 모든 트럭이 다리를 건너는 최소의 시간
for(int i = 0; i < truck_weights.length; i++) { // 향상된 for문을 쓰는게 좋을 것
int truck = truck_weights[i];
while(true) {
// [1] 큐가 비어있는 경우 = 어떠한 트럭도 다리위에 없는 경우
if(queue.isEmpty()) {
queue.add(truck);
sum += truck;
time++; // 다리에 오를 때만 시간 추가
break;
} else if(queue.size() == bridge_length) { // [2] 큐가 가득찬 경우
sum -= queue.poll();
} else { // [3] 큐가 다리 길이만큼 가득 차지 않는 경우
// weight 값을 넘지 않는 선에서 새로운 트럭을 다리에 올려줌
if(sum + truck <= weight) {
queue.add(truck);
sum += truck;
time++;
break;
} else {
// weight 값을 넘는다면, 0을 넣어 이미 큐에 있는 트럭이 다리를 건너게 만듬
queue.add(0);
time++;
}
}
}
}
// 마지막 트럭에서 반복문이 끝나는데, 마지막 역시 다리 길이만큼 지나가야 하기 때문에, 다리 길이만큼 더해준다.
return time + bridge_length;
}
}
트럭 여러 대가 강을 가로지르는 일차선 다리를 정해진 순으로 건너려 한다. => 큐
를 사용한다.
큐를 다리라고 생각하고, 조건에 맞게 트럭을 큐에 넣고 빼면서 최소 몇 초가 걸리는 지 return 하면 되는 문제였다.
고려해야할 사항
다리에는 트럭이 최대 bridge_length
대 올라갈 수 있고, 다리는 weight
이하까지의 무게를 견딜 수 있다.
다리에 완전히 오르지 않는 트럭의 무게는 무시한다 == 다리를 건너는 트럭의 무게만 측정한다 => 같은 의미.
트럭이 다리에 올라가면 1초가 시작되고, 다리 위에서 1칸씩 움직일 때마다 역시 1초가 흘러간다.
다리에 트럭을 넣는 조건은 총 3가지다.
[1] 큐가 비어있는 경우 -> 트럭을 다리에 올려준다 (시간은 +1 증가)
[2] 큐가 가득찬 경우 -> 이때는 가장 앞에 넣은 트럭이 다리의 끝에 도달했다는 의미이므로 poll() 메서드를 이용해 트럭을 꺼내 줌으로써, 다리를 건너가도록 한다. 이때 다리에서 내릴 때는 시간이 들지 않는다.
[3] 큐가 다리 길이만큼 가득 차지 않는 경우 -> 큐에 이미 있는 트럭에 다리를 지나갈 수 있도록 0 값을 넣어준다. (시간은 +1 증가)
이 과정을 전체 트럭의 개수만큼 반복한다.
위의 반복문의 특성상 마지막 트럭의 경우 다리에는 올랐지만 다 건너지는 못한다. 그래서 정답을 출력할 때는 지금까지 걸린 time에서 마지막 트럭이 건너는데 걸리는 시간인 다리의 길이
를 더해서 출력하면 된다.
// 다리를 지나는 트럭(23.12.18) - 1차 복습
import java.util.*;
class Solution {
public int solution(int bridge_length, int weight, int[] truck_weights) {
int sum = 0; // 현재 다리를 지나는 트럭 무게의 합
int time = 0; // 모든 트럭이 다리를 건너는 최소 시간의 합(걸린 시간)
Queue<Integer> bridgeQueue = new LinkedList<>(); // 다리를 지나기 전 트럭
for(int truck : truck_weights) {
while(true) {
// 1. 큐가 비어있는 경우 트럭 추가
if(bridgeQueue.isEmpty()) {
bridgeQueue.offer(truck);
sum += truck;
time++; // 다리에 오를 때만 시간 추가
break;
}
// 2. 다리에 건너는 트럭 무게의 합 == 견딜 수 있는 최대무게(weight)
else if(bridgeQueue.size() == bridge_length) {
sum -= bridgeQueue.poll();
}
// 3. 큐가 비어있지 않은 경우
else {
// 2-2. (다음 트럭까지 포함하여) 다리에 건너는 트럭 무게의 합 > 견딜 수 있는 최대 무게
if(sum + truck > weight) {
bridgeQueue.offer(0);
time++;
}
// 2-3. (다음 트럭까지 포함하여) 다리에 건너는 트럭 무게의 합 < 견딜 수 있는 최대 무게
else {
bridgeQueue.offer(truck);
sum += truck;
time++;
break;
}
}
}
}
// 걸린 시간 + 마지막 트럭의 통과 시간
return time + bridge_length;
}
}
큐를 이용해서 문제를 풀어야 겠다는 생각은 가졌지만, 경우의 수를 생각하는 데 있어서 어려움이 있었다.
단순히 머리로만 생각하지말고, 뭔가 생각할 게 많다고 생각하면 그림을 그리면서 풀어가는 습관을 가지도록 하자.
import java.util.*;
class Solution {
public int[] solution(int[] prices) {
int[] answer = new int[prices.length];
for(int i = 0; i < answer.length; i++) {
for(int j = i + 1; j < answer.length; j++) {
answer[i]++;
if(prices[i] > prices[j]) break;
}
}
return answer;
}
}
import java.util.*;
class Solution {
public int solution(int[] priorities, int location) {
Queue<Pair> queue = new LinkedList<>();
int answer = 0;
for(int i = 0; i < priorities.length; i++) {
queue.add(new Pair(i, priorities[i]));
}
while(!queue.isEmpty()) {
int current = queue.peek().value;
boolean flag = false;
for(Pair pair : queue) {
if(pair.value > current) {
flag = true;
break;
}
}
if (flag) { //우선순위가 높은게 있으면 뒤로 보낸다.
Pair temp = queue.poll();
queue.add(temp);
} else {
answer++;
Pair pair = queue.poll();
if(pair.index == location) {
return answer;
}
}
}
return answer;
}
class Pair {
int index;
int value;
public Pair(int index, int value) {
this.index = index;
this.value = value;
}
}
}
import java.util.*;
class Solution {
public int solution(int[] priorities, int location) {
// 1. 큰 수가 우선순위를 갖는 우선순위 큐
PriorityQueue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());
int answer = 0;
//2. 우선순위 큐에 배열값 넣어주기
for (int i = 0; i < priorities.length; i++) {
pq.add(priorities[i]);
}
// 3. 큐의 값이 없어지기 전까지 반복
while (!pq.isEmpty()) {
for (int i = 0; i < priorities.length; i++) {
// 4.만약 큐의 가장 높은 숫자가 배열의 i번째 index값과 같다면
if (priorities[i] == pq.peek()) {
// 5.값과 위치가 모두 같다면 answer 리턴
if (i == location) {
answer++;
return answer;
}
// 6.값만 일치하는 경우 해당 문서 출력
pq.poll();
answer++;
}
}
}
return -1;
}
}
import java.util.*;
class Solution {
public int solution(int[] priorities, int location) {
int answer = 0;
Queue<Pair> queue = new LinkedList<>();
for(int i = 0; i < priorities.length; i++) {
queue.add(new Pair(i, priorities[i]));
}
while(!queue.isEmpty()) {
int currnet = queue.peek().value;
boolean flag = false;
for(Pair pair : queue) {
if(pair.value > currnet) { // 현재 값보다 나머지 값이 우선순위가 더 높다면
flag = true;
break;
}
}
if(flag) {
Pair temp = queue.poll();
queue.add(temp);
} else {
// 현재 값이 나머지 값보다 우선순위가 더 높다면 answer++
answer++;
Pair pair = queue.poll();
if(pair.index == location) { // 현재 찾고자 하는 위치이면 출력
return answer;
}
}
}
return answer;
}
class Pair {
int index;
int value;
public Pair(int index, int value) {
this.index = index;
this.value = value;
}
}
}
1번은 그냥 큐로 구현한 것이고, 2번은 우선순위 큐로 구현한 것이다.
문제에 대한 설명을 읽고 직관적으로 큐를 사용해서 구현해야 했다.
큐에 남아있는 값들 중 방금 뽑은 값보다 더 높은 우선순위가 있으면 다시 큐에 넣는 식으로 했다.
import java.util.*;
class Solution {
public int[] solution(int[] progresses, int[] speeds) {
Queue<Integer> q = new LinkedList<>();
List<Integer> answerList = new ArrayList<>();
for(int i = 0; i < speeds.length; i++) {
double remain = (100 - progresses[i]) / (double) speeds[i];
int date = (int) Math.ceil(remain); //Math.ceil: 올림
if(!q.isEmpty() && q.peek() < date) { //3 < 5
answerList.add(q.size());
q.clear();
}
q.offer(date);
}
answerList.add(q.size());
int[] answer = new int[answerList.size()];
for(int i = 0; i < answer.length; i++) {
answer[i] = answerList.get(i);
}
return answer;
}
}