반응형

조건에 맞는걸 중간부터 찾으려고 했음 -> 넘 어려움

배열이 주어지면 배열을 앞에나 뒤부터 순회하는게 젤 나은듯

import java.util.*;

class Solution {
    public int solution(int[] citations) {
        int h = citations.length;
        Arrays.sort(citations);
        
        /*배열 순회하기
        for(int c : citations){
            if(c >= h){
                return h;
            }else{
                h -= 1;
            }
        }
        return h;
        */
        
        //길이기준 순회
        int index = 0;
        for(int i=h;i>0;i--){
            if(citations[index] >= i){
                return i;
            }else{
                index +=1;
            }
        }
        return 0;

    }
}
//,0,0]
//h=3 index=0;
//h=2 index 1;
//h=1

//길이 7 
//[1,2,3,5,6,7,8]
//뒤에부터 
//h = 7 일때 index[0] 1 의 값이 7이상이냐? 
//h = 6 일때 index[1] 2 의 값이 6이상이냐?
//h = 5 일때 index[2] 3 의 값이 5 이상이냐?
//h= 4 일때 index[3] 5의 값이 4 이상이냐? -> h반환

//index[0] 일때 h=len index[]의 값이 h 이상이냐?
//index[1]일때 h= len-1

//배열 -> 배열기준순회
반응형
반응형

개선할점

- 반복문 쓸 때 길이조건 변수 헷갈리지 말고 제대로 좀 넣어야한다.

- char 타입데이터에 int 더하면 int 나오니까 (char) 형변환 

class Solution {
    public String solution(String s, String skip, int index) {
        StringBuilder result = new StringBuilder();
        for(int i=0;i<s.length();i++){
           result.append(getAlphabet(s.charAt(i),skip,index));
        }
        return result.toString();
    }
    
    //index만큼 뒤에 있는 알파벳 찾기. skip에 있는거 빼고.
    public String getAlphabet(char c, String skip, int index){ 
        int count = 0 ;
        char standardChar = c; //standardChar = 'x' , count 4 
        while(true){
            char nextChar = standardChar == 'z' ?  'a' : (char)(standardChar + 1);//y
            standardChar = nextChar; //y
            //skip에 없으면
            if(skip.indexOf(Character.toString(nextChar)) == -1){
                count += 1;
            }
            
            if(count == index){
                break;
            }
        }
        
        return Character.toString(standardChar);
    }
}



//charAt(i) 문자 +1반복.. count index만큼 채울때까지..
//기준문자는 계속 바꾼다 
//문자가 z라면.. a로바꾸고..
반응형
반응형

개선할점

HashMap 초기화 하지 않고 put 메서드 호출하려 하면 nullPointException 나므로 조심.

메서드 나누니까 편하긴 하다

import java.util.*;
class Solution {
    String mainHand;
    int[] leftPosition = {1,4};
    int[] rightPosition = {3,4};
    HashMap<Integer,int[]> phone = new HashMap<>();
    
    public String solution(int[] numbers, String hand) {
        mainHand = hand.equals("right")? "R" : "L";
        phone.put(1,new int[]{1,1});
        phone.put(2,new int[]{2,1});
        phone.put(3,new int[]{3,1});
        phone.put(4,new int[]{1,2});
        phone.put(5,new int[]{2,2});
        phone.put(6,new int[]{3,2});
        phone.put(7,new int[]{1,3});
        phone.put(8,new int[]{2,3});
        phone.put(9,new int[]{3,3});
        phone.put(0,new int[]{2,4});
        
        StringBuilder answer = new StringBuilder();
        for(int i=0;i<numbers.length;i++){
            answer.append(getHand(numbers[i]));
        }
       
        return answer.toString();
    }
    
    
    //어느 손으로 누를지 계산 -> 현재위치 이동하기
    public String getHand(int num){
        String leftOrRight = switch(num){
                case 1,4,7 -> "L";
                case 3,6,9 -> "R";
                case 2,5,8,0 -> whenMiddle(num);
                default -> mainHand;
        };
        //손 이동하기 
        makePosition(num,leftOrRight);
        
        return leftOrRight;
    }
        
    //가운데일때 어느손으로 누를지 계산
    public String whenMiddle(int num){
        int[] numPosition = phone.get(num);
        int leftHandDistance = Math.abs(leftPosition[0]-numPosition[0])
                            + Math.abs(leftPosition[1]-numPosition[1]);
        int rightHandDistance = Math.abs(rightPosition[0]-numPosition[0])
                            + Math.abs(rightPosition[1]-numPosition[1]);
    
        if(leftHandDistance == rightHandDistance){
            return mainHand;
        }else if(leftHandDistance  < rightHandDistance){
            return "L";
        }else{
            return "R";
        }
    }
    
    //현재위치 이동하기    //누를 숫자   //누를 손
    public void makePosition(int num, String whatHand){
        if(whatHand.equals("L")){
            leftPosition = phone.get(num);
        }else{
            rightPosition = phone.get(num);
        }
    }
}

//현재위치 [1,3],[2,4]이렇게
//현재위치 lefthand=4   1->1, 4->2, 7->3, *->4
//현재위치 righthand=4  3->1, 6->2, 9->3, #->4
//숫자가 1,4,7이면 -> L 
//숫자가 3,6,9이면 -> R 
//숫자가 2,5,8,0이면 2->1, 5->2, 8->3, 0->4 로 해서 가까운걸로 같으면 hand 참고
//가운데 누르고 난뒤
반응형
반응형

틀린 이유

1. substring(start, end) 인덱스 헷갈림

//i부터 맨뒤까지 모두 자르기
str.substring(i);
str.substring(i,str.length);

//end보다 하나 전까지 가져옴

2. 오류파악 String index out of range: 0 

-> index0 도 없다는건 길이가 0이라는것. substring 결과의 길이가 0일때의 케이스 고려를 안 함

반응형
반응형

List 정렬하는법

//기본 오름차순
Collections.sort(list);

//내림차순
Collections.sort(names, Collections.reverseOrder());

//person 객체의 age로 정렬하기
Collections.sort(list,Comparator.comparingInt(person -> person.age))

//문자열의 길이를 기준으로 정렬
Collections.sort(names, Comparator.comparingInt(String::length));

 

import java.util.*;

class Solution {
    public int[][] solution(int[][] data, String ext, int val_ext, String sort_by) {
        
        HashMap<String,Integer> columnInfo= new HashMap<>();
        columnInfo.put("code",0);
        columnInfo.put("date",1);
        columnInfo.put("maximum",2);
        columnInfo.put("remain",3);
        
        
        //조건 인덱스
        int extIndex = columnInfo.get(ext);
        //정렬 인덱스
        int sortIndex = columnInfo.get(sort_by);
        
        List<int[]> newData = new ArrayList<>();
        for(int i=0;i<data.length;i++){
            int[] detailData = data[i];
            //조건부합하는지 검사
            if(detailData[extIndex] < val_ext){
                newData.add(detailData);
            }           
        }
        
        //List 정렬
        Collections.sort(newData,Comparator.comparingInt(list->list[sortIndex]));
        //Collections.sort(newData,(a,b)->Integer.compare(a[sortIndex],b[sortIndex]));
       
        

        
        int[][] answer = new int[newData.size()][4];
        answer = newData.toArray(new int[0][]);
     
        return answer;
          
    }
}
반응형
반응형

배열 정렬

Arrays.sort();

배열 비교

Arrays.mismatch();

import java.util.*;

class Solution {
    public String solution(String[] participant, String[] completion) {
        Arrays.sort(participant);
        Arrays.sort(completion);
        int mismatchIndex = Arrays.mismatch(participant,completion);
        return participant[mismatchIndex];
        
    }
}

 

다른방법

맵의 key-value에 접근하는법

Set<Map.Entry<String, Integer>> entrySet = map.entrySet();

 

맵의 모든 key 가져오기

 Set<String> keys = map.keySet();

 

맵의 모든 value 가져오기

Collection<String> values = map.values();

 

 

import java.util.*;

class Solution {
    public String solution(String[] participant, String[] completion) {
        HashMap<String,Integer> particimap = new HashMap<>();
        for(String name : participant){
            int cnt = particimap.getOrDefault(name,0);
            particimap.put(name,++cnt);
        }
        
        for(String name : completion){
            int cnt = particimap.get(name);
            particimap.put(name,--cnt);
        }
        
        return particimap.entrySet()
            .stream()
            .filter(entry -> entry.getValue() >0)
            .map(Map.Entry::getKey)
            .findFirst()
            .orElse("없음");
    }
}

 

 

반응형

'코딩 관련 > 코딩문제풀기' 카테고리의 다른 글

[프로그래머스] 키패드 누르기  (0) 2024.10.09
[프로그래머스] 문자열 나누기  (0) 2024.10.06
[프로그래머스] 숫자 짝꿍  (0) 2024.10.04
[JAVA] 9012번 괄호  (0) 2023.03.13
[JAVA] 너의 평점은  (0) 2023.03.12
반응형

개선사항

1. 두 정수 비교시 for문 보다는 Math.min() 사용하기

2. String 에서 문자 하나 추출시 substring(i,i-1) 보다는 charAt() 사용하기

3. char 을 정수형으로 변환

//1.'0'빼기. '0'의 ASCII값 : 48
int text1 = '1';
int num1 = text1 - '0';

//2. Character.getNumericValue() 
int text2 = '1';
int num2 = Character.getNumericValue(text2);
반응형

'코딩 관련 > 코딩문제풀기' 카테고리의 다른 글

[프로그래머스] 문자열 나누기  (0) 2024.10.06
[프로그래머스] 완주하지 못한 선수  (0) 2024.10.04
[JAVA] 9012번 괄호  (0) 2023.03.13
[JAVA] 너의 평점은  (0) 2023.03.12
[JAVA] 그룹 단어 체커  (0) 2023.03.12
반응형

N+1 이란?

예를 들어 Stuedent 엔티티에 GradeInfo엔티티와 ClassInfo엔티티가 EAGER Loading으로 연관매핑된 경우

@Comment("교실정보")
@ManyToOne //디폴트 값은 (fetch = FetchType.EAGER)
@JoinColumn(name = "class", referencedColumnName = "classId")
private ClassInfo class;


@Comment("학년정보")
@ManyToOne
@JoinColumn(name = "grade", referencedColumnName = "gradeId")
private GradeInfo grade;

아래와 같은 JPA 쿼리메소드를 사용할 때

studentRepository.findAll();

findAll() 수행 시점에 Student 엔티티를 조회하는 select 쿼리와

+ 매핑된 GradeInfo 엔티티를 조회하는 select 쿼리,

+ 매핑된 ClassInfo 엔티티를 조회하는 select 쿼리,

모두 수행된다.

예를 들어 1000개의 Student 엔티티는 각각 1,2,3,4,5,6 이라는 6개 중 하나의 gradeInfo 값을 가질 수 있고

1-1, 1-2, 1-3, 1-4, 1-5, 1-6 부터 6학년 6-6 까지 이라는 총 36개중 하나의 ClassInfo 값을 가질 수 있다하면

전체 Student 를 조회할 시 student에 연관된 GradeInfo 엔티티를 조회하기 위해 총 6번의 select,

ClassInfo 엔티티를 조회하기 위한 36번의 select가 추가로 나감. 이것을 N+1 문제라고 함

 

왜 join으로 쿼리 생성이 되지 않고 select가 각각 나가는걸까

=> JPA가 메소드 이름을 분석해서 JPQL을 생성하고 실행함.
=> JPQL을 생성할때는 fetch 전략을 참고하지 않기 때문

 

LAZY Loading 전략을 사용하면 N+1문제가 해결되나?

=> 해당 엔티티에 연관매핑된 엔티티를 조회(사용)할 때 select가 추가로 나가게 됨. 

=> 또는 엔티티 return 시에 결국 select하게 됨

=> 해결 안 됨

 

QueryDSL을 사용해도 N+1 문제가 생기나

QueryDSL은 JPQL 빌더역할을 해주는 것이기 때문에 QueryDSL 로 entity select하는 경우에도 발생함.

leftJoin을 걸어놨지만 join이 되지않고 select가 각각 나간다.

public List<Goods> nplus1test(){
        List<Student> result = queryFactory
                    .select(qStudent) 
                    .from(qStudent)
                    .leftJoin(qStudent.grade,qGradeInfo)
                    .leftJoin(qStudent.class,qClassInfo)  
                    .fetch();

 

entity 전체가 아닌 컬럼을 지정해서 뽑는다면 해결되나

컬럼 지정시 join이 되지만 컬럼을 지정해서 뽑으면 tuple 로 반환되어  불편함

public List<Tuple> nplus1test(){
  List<Tuple> result = queryFactory
                                  .select(qStudent.name,qStudent.grade)
                                  .from(qStudent)
                                  .fetch();
  for(Tuple tuple : result){
          System.out.println(tuple.get(qStudent.name));
          System.out.println(tuple.get(qStudent.grade));
  }
  return result;
}

=> Projections.bean 혹은 Projections.fields를 사용해 DTO를 반환받으면 됨

 

그래도 entity 전체를 select하고 싶다면

EntityGraph를 사용하면 됨

EntityGraph : DataJPA에서 fetchjoin을 어노테이션으로 사용할 수 있도록 하였다. 연관관계가 지연로딩으로 되어있는 엔티티를 조회할 경우 fetch join을 사용한다. 

fetchjoin : select 대상 엔티티와 fetch join이 걸려있는 엔티티를 포함해 join하여 select 함. 

EntityGraph 사용 예시

@EntityGraph(attributePaths = {"class","grade"})
List<Student> findAll();

 

fetchjoin 사용 예시

@Override
public List<Goods> nplus1test(){
        List<Goods> result = queryFactory
                    .select(qStudent)
                    .from(qStudent)
                    .leftJoin(qStudent.class,qClassInfo)
                    .fetchJoin()  
                    .leftJoin(qStudent.grade,qGradeInfo)
                    .fetchJoin()    
                    .fetch();
        return result;
}
반응형
반응형

"Must create a new ApplePaySession from a user gesture handler"라는 에러는 Apple의 보안 정책 중 하나입니다. 이 에러는 사용자 동작(user gesture) 없이 Apple Pay 세션을 시작하려고 할 때 발생할 수 있습니다. Apple은 사용자의 명시적인 동의 없이 결제를 진행하거나 개인 정보를 요청하는 것을 방지하기 위해 이러한 정책을 시행합니다.

따라서 Apple Pay 세션을 시작하는 코드는 사용자의 명시적인 동작에 반응하여 실행되어야 합니다. 사용자가 버튼을 클릭하거나 터치할 때 세션을 시작하도록 구현해야 합니다. 사용자 동작 이벤트 핸들러 내부에서 Apple Pay 세션을 시작하도록 코드를 변경해야 합니다.

다시 말씀드리면, Apple Pay 세션을 시작하는 함수는 사용자가 버튼을 클릭하거나 터치하는 등의 동작에 반응하여 호출되어야 합니다. 사용자 동작과 관련된 이벤트 핸들러 내에서 해당 함수를 호출하십시오. 이렇게 하면 보안 정책을 준수하면서도 사용자가 Apple Pay를 시작하도록 허용됩니다.

반응형
반응형

1. kafka client 다운로드 

https://kafka.apache.org/downloads

Binary 다운로드
tgz파일 압축 풀어서 C에 갖다놓기
(실행시 path가 길면 "입력 줄이 너무 깁니다." 가 뜨기 때문)

 

2. 클러스터에 연결하기 위해 IAM 인증을 사용할 것이므로 IAM 인증용 jar 다운로드

https://github.com/aws/aws-msk-iam-auth/releases
jar 파일을 libs 폴더 밑에 넣는다.(C에 위치한 경우 C:\kafka_2.13-3.6.1\libs 의 밑 ) 

 

 

3. config 폴더 밑에 client.properties 파일 생성하여 아래 내용 입력

security.protocol=SASL_SSL
sasl.mechanism=AWS_MSK_IAM
sasl.jaas.config=software.amazon.msk.auth.iam.IAMLoginModule required;
sasl.client.callback.handler.class=software.amazon.msk.auth.iam.IAMClientCallbackHandler

 

cmd에서 bin\windows로 가서 명령어 입력하면 됨

 

토픽 리스트 조회
kafka-topics.bat --list --bootstrap-server [브로커엔드포인주소]:[포트] --command-config C:\kafka_2.13-3.6.1\config\client.properties

토픽 삭제
kafka-topics.bat --bootstrap-server [브로커엔드포인주소]:[포트] --delete --topic [토픽이름] --command-config C:\kafka_2.13-3.6.1\config\client.properties

토픽 생성
kafka-topics.bat --bootstrap-server [브로커엔드포인주소]:[포트] --create --topic [토픽이름] --partitions [개수] --replication-factor [개수] --command-config C:\kafka_2.13-3.6.1\config\client.properties

토픽 구성정보 조회
kafka-topics.bat --topic [토픽이름] --describe --bootstrap-server [브로커엔드포인주소]:[포트] --command-config C:\kafka_2.13-3.6.1\config\client.properties

토픽의 record 조회
kafka-console-consumer.bat --bootstrap-server [브로커엔드포인주소]:[포트] --topic [토픽이름] --from-beginning --consumer.config C:\kafka_2.13-3.6.1\config\client.properties --property print.offset=true --property print.timestamp=true --property print.key=true

토픽에 메세지 발행
kafka-console-producer.bat --topic order-status --bootstrap-server b-2.mskdominos.ormjxv.c2.kafka.ap-northeast-2.amazonaws.com:9098 --producer.config C:\kafka_2.13-3.6.1\config\client.properties

클러스터에 연결된 컨슈머 그룹 리스트 조회
kafka-consumer-groups.bat --bootstrap-server [브로커엔드포인주소]:[포트] --command-config C:\kafka_2.13-3.6.1\config\client.properties --list
amazon.msk.canary.group.broker-1

컨슈머 그룹 오프셋 정보 조회
kafka-consumer-groups.bat --bootstrap-server [브로커엔드포인주소]:[포트] --command-config C:\kafka_2.13-3.6.1\config\client.properties --describe --group [그룹이름] --offsets

반응형

+ Recent posts