//////
Search
📓

10/24 회고록

생성일
2022/10/24 08:59
태그

김기헌

Programmers - K번째 수 (Priority_Queue)

import java.util.PriorityQueue; class Solution { public int[] solution(int[] array, int[][] commands) { int[] answer = new int[commands.length]; PriorityQueue<Integer> pq = new PriorityQueue<>(); for (int i = 0; i < commands.length; i++) { int left = commands[i][0]-1; //자를 지점의 left, right값 설정 int right = commands[i][1]; int n = commands[i][2]; for (int j = left; j < right; j++){ pq.add(array[j]); } for (int j = 0; j < n; j++){ answer[i] = pq.poll(); } pq.clear(); } return answer; } }
Java
복사
Priority_Queue는 주어진 기준에 따라 우선순위가 가장 높은 값을 최상단에 가지고 있기에 (위의 코드에서는 오름차순) n번째의 수를 뽑기 위해 n번 poll(pop)작업을 해주었다
우선순위 큐는 완전 이진 트리이며, 완전히 정렬된 상태가 아닌, 부모 노드가 자식 노드보다 우선순위가 높은 상태이다(반정렬 상태) 즉, Node의 인덱스 순서대로 출력할 시 정렬된 상태를 보장하지 않는다.

Programmers - 가장 큰 수

class Solution { public String solution(int[] numbers) { String[] s = new String[numbers.length]; StringBuilder sb = new StringBuilder(); for (int i = 0; i < numbers.length; i++) s[i] = String.valueOf(numbers[i]); Arrays.sort(s, new Comparator<String>() { //사전 순 내림차순 정렬 public int compare(String s1, String s2) { if (s1.charAt(0) == s2.charAt(0)) { int n1 = Integer.parseInt(s1 + s2); int n2 = Integer.parseInt(s2 + s1); return n2 - n1; } return s2.charAt(0) - s1.charAt(0); } }); for (int i = 0; i < s.length; i++) sb.append(s[i]); if (sb.charAt(0) == '0') return "0"; return sb.toString(); } }
Java
복사

Toby spring

Context, DI
Template Callback
JdbcTemplate

김상호

final이란?

변수, 메소드, 클래스에 사용 가능하며, 한번 값을 선언하면 - 변수인 경우엔 값 변경 불가 - 클래스인 경우엔 상속을 허용하지 않음, - 메소드인 경우엔 오버라이딩을 금지합니다.
final 변수 예제
final 메소드 예제
final 클래스 예제

final의 장점

1.
보안
2.
메모리를 적게 차지
3.
성능 향상

JdbcContext로 분리

다른 Dao에서도 사용 가능하게 하기 위해 UserDao에서 분리 시켜줍니다.
JdbcContext 코드

이가현

알고리즘

k번째 수
Array이용하는 방법
public class Kth { public static void main(String[] args) { Kth kth = new Kth(); /* int[] arr = {1,5,2,6,3,7,4}; int[][] commands ={{2,5,3},{4,4,1},{1,7,3}};*/ int[] answer = kth.solution(new int[]{1, 5, 2, 6, 3, 7, 4}, new int[][]{{2, 5, 3}, {4, 4, 1}, {1, 7, 3}}); System.out.println(Arrays.toString(answer)); } public int[] solution(int[] arr, int[][] commands) { int[] answer = new int[commands.length]; //2차원의 배열의 행길이 for (int i = 0; i < commands.length; i++) { int[] temp = Arrays.copyOfRange(arr, commands[i][0] - 1, commands[i][1]); Arrays.sort(temp);//정렬 answer[i] = temp[commands[i][2] - 1]; } return answer; } }
Java
복사
우선순위큐를 이용한 K번째 수
public class KthQueue { public int[] solution(int[] arr, int[][] commands) { int[] answer = new int[commands.length]; for (int i = 0; i < commands.length; i++) { PriorityQueue<Integer> pq = new PriorityQueue<>(); for (int j = commands[i][0]-1; j < commands[i][1]; j++) { pq.add(arr[j]); } for (int j = 0; j < commands[i][2]; j++) { answer[i] = pq.poll(); } } return answer; } public static void main(String[] args) { KthQueue kthNum = new KthQueue(); int[] arr = new int[]{1, 5, 2, 6, 3, 7, 4}; int[][] commands = new int[][]{{2, 5, 3}, {4, 4, 1}, {1, 7, 3}}; System.out.println(Arrays.toString(kthNum.solution(arr, commands)));; } }
Java
복사

토비의 Spring

복습하기-강사님 유튜브 강의 https://youtu.be/7ofp3OubAkg
1.
StatementStrategy interface정의 – 222p
2.
StatementStrategy interface를 구현한 DeleteAllStrategy() 구현 – 222p
3.
UserDao의 deleteAll()에 적용 – 225p
4.
deleteAll()에서 jdbcContextWithStatementStrategy분리 – 225p
5.
deleteAll()에서 jdbcContextWithStatementStrategy(StatementStrategy stmt) 호출하게 적용 – 225p
6.
AddStrategy() 구현 – 227p
7.
UserDao의 add()에 적용 – 228p
docker 내려가는분--비밀번호 유출에 의한 해킹 가능성
DataSource인터페이스 적용 138p
LocalConnectionMaker → LocalDataSource
xml설정 → Spring Boot 에서는 많이 없어짐.
DataSource는 Java에 내장 인터페이스
코드
DI할 때 final을 쓰는 이유
final(불변) : 한번 초기화 되면 바꿀 수 없는 것. <장점>
1.
신뢰성 - 불변이기 때문에 변화를 고려하지 않음
2.
Memory 적게 차지. → 변화가 없기때문에 여분의 메모리 할당하지 않음
<final을 쓰는 이유>
1.
Spring에서 DI되었다면 이미 Factory에서 조립이 끝난 상태이므로 변화하지 않는게 좋다.
2.
변화하지 않는게 좋으므로 final로 쓰는게 좋다. 왜냐하면 메모리 사용에 유리하고 신뢰성 있기 때문
3.
이후 SpringBoot에서 @Autowired하는 부분이 final로 대체하는 것을 권장하게 바뀜.
익명 클래스 도입
StatementStrategy Interface의 구현체인 DeleteAllStrategy()를 쓰는 곳이 deleteAll()한군데 뿐이기 때문에 이렇게 한번만 쓰는 경우는 내부 클래스를 쓰기
코드
JdbcContext로 분리 234p
jdbcContextWithStatementStrategy는 다른 Dao에서도 쓰기 위해 UserDao에서 분리
jdbcContextWithStatementStrategy를 복사
JdbcContext는 클래스 이름으로 썼으므로 workWithStatementStrategy라는 메소드 이름 설정
코드
UserDao에 JdbcContext 의존하게 변경
new JdbcContext(dataSource); 구체적인 클래스 이름이 들어가는 구간?
코드
@Bean 은 언제 쓰는가? - Spring의 ApplicationContext에 등록하는 빈을 만들 때
ex) AwsUserDao 등 재료가 되는 @Bean 도 붙여주는 경우가 있습니다.
-조립의 재료로만 쓴다면 ApplicationContext에 등록을 안해줘도 됩니다
JdbcTemplate적용 262p
JdbcTemplate이 JdbcContext를 완전히 대체 합니다.

조국현

알고리즘 - K번째 수

내장메소드를 통해서, 비교적 빠르게 구현이 가능한 문제였다
public int[] solution(int[] arr, int[][] commands) { int[] answer = new int[commands.length]; int idx = 0; for (int[] command :commands) { int[] slicedArr = Arrays.copyOfRange(arr, command[0]-1, command[1]); // array를 slice합니다. Arrays.sort(slicedArr); answer[idx++] = slicedArr[command[2]-1]; } return answer; }
Java
복사
배열에 저장된 각 command들을 다시 1차원 배열로 차례대로 뽑아서, 정렬 뒤 slicedArr[command[2]-1] 의 값을 읽어주면 된다.

알고리즘 - K번째 수 (우선순위 큐)

위의 내장메소드를 사용한 방법이 아니라, 이번에는 우선순위 큐라는 자료구조를 이용했다. 우선순위 큐이므로 정렬이 자동으로 진행되어서 sort를 따로 써주지 않아도 된다. 자료구조에 아직 익숙하지 않았지만 선입선출이라는 점을 잘 이해하고 사용법을 익히면 푸는 것은 비슷하다.
public int getKthNum(int[] command) { int frIdx = command[0]; // 0번 from int toIdx = command[1]; // 1번 to int nth = command[2]; // n번째 int result = 0; // 문제에 0이 안나온다고 했기 때문에 3벌식 PriorityQueue<Integer> pq = new PriorityQueue<>(); for (int i = frIdx-1; i < toIdx ; i++) { // 1번부터 시작하니 -1 pq.add(arr[i]); } for (int i = 0; i < nth; i++) { result = pq.poll(); // stack의 pop과 비슷 } return result; } public int[] solution(int[] arr, int[][] commands) { this.arr = arr; int[] answer = new int[commands.length]; for (int i = 0; i < commands.length; i++) { answer[i] = getKthNum(commands[i]); } return answer; }
Java
복사

DataSource 인터페이스 적용

AWSConnectionMaker를 자바 내장 인터페이스인 DataSource를 적용해서 쉽게 구현할 수 있다.
@Configuration public class UserDaoFactory { @Bean UserDao awsUserDao() { return new UserDao(dataSource()); } @Bean DataSource dataSource() { Map<String, String> env = System.getenv(); SimpleDriverDataSource dataSource = new SimpleDriverDataSource(); dataSource.setDriverClass(com.mysql.cj.jdbc.Driver.class); dataSource.setUrl(env.get("DB_HOST")); dataSource.setUsername(env.get("DB_USER")); dataSource.setPassword(env.get("DB_PASSWORD")); return dataSource; } }
Java
복사
@Configuration public class UserDaoFactory { @Bean UserDao awsUserDao() { return new UserDao(awsDataSource()); } @Bean UserDao localUserDao() { return new UserDao(localDataSource()); } @Bean DataSource awsDataSource() { Map<String, String> env = System.getenv(); SimpleDriverDataSource dataSource = new SimpleDriverDataSource(); dataSource.setDriverClass(com.mysql.cj.jdbc.Driver.class); dataSource.setUrl(env.get("DB_HOST")); dataSource.setUsername(env.get("DB_USER")); dataSource.setPassword(env.get("DB_PASSWORD")); return dataSource; } @Bean DataSource localDataSource() { Map<String, String> env = System.getenv(); SimpleDriverDataSource dataSource = new SimpleDriverDataSource(); dataSource.setDriverClass(com.mysql.cj.jdbc.Driver.class); dataSource.setUrl("localhost"); dataSource.setUsername("root"); dataSource.setPassword("12345678"); return dataSource; }}
Java
복사
public class UserDao { private DataSource dataSource; // DataSource를 의존하게 변경 public UserDao(DataSource dataSource) { this.dataSource = dataSource; // 생성자도 변경 }public void jdbcContextWithStatementStrategy(StatementStrategy stmt) throws SQLException { Connection c = null; PreparedStatement pstmt = null; try { c = dataSource.getConnection(); // datasource를 사용하게 변경
Java
복사

DI시 final 쓰는 이유

메모리를 적게 쓰므로 메모리 절약이 가능
DI 후 DataSource가 바뀌면 변화 예측이 어렵다.
Factory에서 조립이 끝난 상태이므로 변화되지 않는 것이 좋다.

익명클래스

자바스크립트에서의 익명함수와 사용법이 비슷하다고 느껴졌다. 클래스를 너무 많이 만들어야 하는데 이것을 피하고픈 경우, 한 번만 쓸 경우에는 익명클래스를 활용하는 것이 좋다.
public void deleteAll() throws SQLException { // "delete from users" StatementStrategy deleteAllStrategy = new StatementStrategy() { @Override public PreparedStatement makeStatement(Connection conn) throws SQLException { return conn.prepareStatement("delete from users"); } }; jdbcContextWithStatementStrategy(deleteAllStrategy); }
Java
복사
add()도 익명클래스를 적용하게 되면, user를 생성자로 넘겨주지 않아도 되는 이점이 있다.
public void add(final User user) throws SQLException { // DB접속 (ex sql workbeanch실행) jdbcContextWithStatementStrategy(new StatementStrategy() { @Override public PreparedStatement makeStatement(Connection conn) throws SQLException { PreparedStatement pstmt = null; pstmt = conn.prepareStatement("INSERT INTO users(id, name, password) VALUES(?,?,?);"); pstmt.setString(1, user.getId()); pstmt.setString(2, user.getName()); pstmt.setString(3, user.getPassword()); return pstmt; } }); }
Java
복사

최아영

K번째수

배열로 풀기
우선순위 큐로 풀기

토비의 스프링 3장

DataSource 인터페이스 적용
익명클래스 적용
JdbcContext로 분리
Template Callback 적용
JdbcTemplate 적용