반응형

문제 설명

배열 arr가 주어집니다. 배열 arr의 각 원소는 숫자 0부터 9까지로 이루어져 있습니다. 이때, 배열 arr에서 연속적으로 나타나는 숫자는 하나만 남기고 전부 제거하려고 합니다. 단, 제거된 후 남은 수들을 반환할 때는 배열 arr의 원소들의 순서를 유지해야 합니다. 예를 들면,

  • arr = [1, 1, 3, 3, 0, 1, 1] 이면 [1, 3, 0, 1] 을 return 합니다.
  • arr = [4, 4, 4, 3, 3] 이면 [4, 3] 을 return 합니다.

배열 arr에서 연속적으로 나타나는 숫자는 제거하고 남은 수들을 return 하는 solution 함수를 완성해 주세요.

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

나의 풀이 (java)

import java.util.ArrayList;
import java.util.List;

public class DeleteDuplicate {

    public static void main(String[] args) {
        int[] arr = {1,1,3,3,0,1,1};
        solution(arr);
    }

    public static int[] solution(int []arr) {
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < arr.length; i++) {
            if(i == 0 || arr[i] != arr[i-1]) {
                list.add(arr[i]);
            }
        }
        // Stream을 이용한 List -> int[]
        return list.stream().mapToInt(Integer::intValue).toArray();
    }

}

 

풀이 방법

특별히 어려운 로직은 없고, 아래 2가지만 잘 생각하면 된다

  • 중복 여부 확인 : arr의 index로 이전 값으로 접근해서 중복 여부 체크
  • list <-> array 변환 : 기본형(Integer)이 아닌 int형의 배열로 바꾸기 위해 Stream 사용 

다른사람의 풀이 (java) 

    public int[] solution(int []arr) {
        ArrayList<Integer> tempList = new ArrayList<Integer>();
        int preNum = 10;
        for(int num : arr) {
            if(preNum != num)
                tempList.add(num);
            preNum = num;
        }       
        int[] answer = new int[tempList.size()];
        for(int i=0; i<answer.length; i++) {
            answer[i] = tempList.get(i).intValue();
        }
        return answer;
    }

Godd Idea : 중복 여부를 확인할때, arr의 인덱스가 아닌 이전 값 체크용(preNum) 변수 사용하는게 키포인트

느낀점

 

반응형
반응형

Array → List

원배열을 바꾸면, 복사한 배열도 변경하고 싶은지의 여부에 따라 선택

  • Arrays.asList(arr)
    얕은 복사(원 배열 공유=동기화) List<String> list = Arrays.asList(arr)
  • new ArrayList<>(Arrays.asList(arr))
    깊은복사(새로운 배열=비동기화) List<String> list = Arrays.asList(arr)
  • Collector.toList()
    Stream 사용 List<String> list = Stream.of(arr).collect(Collectors.toList());

List → Array

  • toArray() String arr[] = arrList.toArray(new String[Size])
    Object[]로 리턴이라, 타입 변환이 어려움
  • toArray(T[] t)
    위와 똑같지만 T 타입의 배열 명시 하지만 기본형만 가능(int, double, float은 불가능) [길이] : 길은 size를 직접 넣어도 되고, 0으로 넣으면 자동 조정
  • Stream
    int 등으로 저장할때 유용(Integer→intValue로 int형변환→toArray사용) list.stream().mapToInt(Integer::intValue).toArray();
반응형
반응형

상황

spring으로 만든 서비스가 정상적으로 동작하다가,
작업이 안 되는 경우가 발생해서 로그를 찾아보니, 아래의 내용이 남아있음

 

에러내용

Cause: java.sql.SQLTransientConnectionException:  Lost connection to backend server: network error (server1: Connection reset by peer)

Lost connection to backend server: network error (server1: Connection reset by peer); nested exception is java.sql.SQLTransientConnectionException: Lost connection to backend server: network error (server1: Connection reset by peer)

 

예상 원인

  • 원격 서버에서 Connection을 reset 처리하거나
  • 종료된 커넥션을 재사용하려고 할때
  • 클라이언트(브라우저)에서 정지버튼을 누르거나, 브라우저를 종료하거나, 다른 화면으로 이동하는 등의 이유로 서버 측에서 작업 결과를 전달할 곳이 없어졌을 때
  • Connection에서 Timeout 발생
  • 메모리부족
  • 소켓 고갈 등등…

 

원인

근본적인 원인 

위의 예상원인 모두 실제 원인의 보기이고,
회사에서 해당 이슈가 종종 발생하는 원인은 DB서버의 작업이 있는 경우에 많이 발생

 

DB 서버의 특정 작업(백업, 데이터 이동 등등 IO나 리소스를 많이 잡아먹는 작업)이 진행중

=> DB의 성능저하

=> 평소에 문제없던 쿼리가 실행되지 못하고 타임아웃

조치

근본적인 조치

근본적인 원인을 해결해야 함

DB 서버의 작업 종료 or 해결 : 리소스가 많이 필요한 해당 작업을 빨리 종료 시키면 정상적으로 동작함

하지만 주기적으로 해야하는 작업이라면

쿼리나 서비스 성능 개선을 통해 어느정도 커버할 수 있음

 

쿼리 튜닝으로 해결

타임 아웃 (시간제한) 을 길게 설정하는 방법도 있지만, 근본적으로 쿼리 실행시간이 너무 오래 걸림

평소에는 0.5초도 걸리지 않았지만, 특정상황에서 계속 타임아웃이 나서 튜닝 필요성이 없었음

=> 주기적으로 발생할 것으로 추측돼서, 쿼리 튜닝실행

=> 평소에는 크게 차이 나지 않지만, (최악의 경우에서) 더 효율적인 인덱스를 타면서 쿼리가 개선

=> 같은 상황에서는 더이상 발생하지 않음

반응형
반응형

문제 설명

0 또는 양의 정수가 주어졌을 때, 정수를 이어 붙여 만들 수 있는 가장 큰 수를 알아내 주세요.
예를 들어, 주어진 정수가 [6, 10, 2]라면 [6102, 6210, 1062, 1026, 2610, 2106]를 만들 수 있고, 이중 가장 큰 수는 6210입니다.
0 또는 양의 정수가 담긴 배열 numbers가 매개변수로 주어질 때, 순서를 재배치하여 만들 수 있는 가장 큰 수를 문자열로 바꾸어 return 하도록 solution 함수를 작성해주세요.

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

다른사람의 풀이 (java) = 나의 풀이

import java.util.Arrays;
import java.util.Comparator;

class Solution {
    public String solution(int[] numbers) {

        // 숫자를 문자열로 변환
        String[] result = new String[numbers.length];
        for (int i = 0; i < numbers.length; i++) {
            result[i] = String.valueOf(numbers[i]);
        }

        // 정렬
        Arrays.sort(result, (o1, o2) -> (o2 + o1).compareTo(o1 + o2));

        // 0만 여러개 있는 배열의 경우 하나의 0만 리턴
        if (result[0].equals("0")) {
            return "0";
        }

        String answer = "";
        // 정렬된 문자 하나로 합치기
        for (String a : result) {
            answer += a;
        }
        return answer;
    }
}

풀이 방법

몇몇 테스트 케이스를 통과하지 못하고.. 1시간 정도 고민하다가, 결국 다른 사람의 풀이를 보고 풀었다

관건은 실제로 정렬을 구현하는 부분이었다. 

혼자 힘으로 풀때는 문자 3 vs 30 이 나올때 330이 출력되도록 하는 로직 고민하다가 시간을 다 써버림..

 

중요 포인트 - 두개의 문자를 합쳐 만드는 수의 대소 비교

Arrays.sort(result, (o1, o2) -> (o2 + o1).compareTo(o1 + o2))

 

느낀점

  • Array 정렬 방법
    • 단순 정렬시 - Array.sort(arr)
    • 복잡 정렬시 - Arrays.sort(result, (o1, o2) -> (o2 + o1).compareTo(o1 + o2))

 

반응형
반응형

문제 설명

0 또는 양의 정수가 주어졌을 때, 정수를 이어 붙여 만들 수 있는 가장 큰 수를 알아내 주세요.
예를 들어, 주어진 정수가 [6, 10, 2]라면 [6102, 6210, 1062, 1026, 2610, 2106]를 만들 수 있고, 이중 가장 큰 수는 6210입니다.
0 또는 양의 정수가 담긴 배열 numbers가 매개변수로 주어질 때, 순서를 재배치하여 만들 수 있는 가장 큰 수를 문자열로 바꾸어 return 하도록 solution 함수를 작성해주세요.

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

나의 풀이 = 다른사람의 풀이(java)

import java.util.Arrays;
import java.util.Comparator;

class Solution {
    public String solution(int[] numbers) {

        // 숫자를 문자열로 변환
        String[] result = new String[numbers.length];
        for (int i = 0; i < numbers.length; i++) {
            result[i] = String.valueOf(numbers[i]);
        }

        // 정렬
        Arrays.sort(result, (o1, o2) -> (o2 + o1).compareTo(o1 + o2));

        // 0만 여러개 있는 배열의 경우 하나의 0만 리턴
        if (result[0].equals("0")) {
            return "0";
        }

        String answer = "";
        // 정렬된 문자 하나로 합치기
        for (String a : result) {
            answer += a;
        }
        return answer;
    }
}

풀이 방법

몇몇 테스트 케이스를 통과하지 못하고.. 1시간 정도 고민하다가, 결국 다른 사람의 풀이를 보고 풀었다

관건은 실제로 정렬을 구현하는 부분이었다. 

혼자 힘으로 풀때는 문자 3 vs 30 이 나올때 330이 출력되도록 하는 로직 처리하다가 너무 복잡해짐

결론
Arrays.sort(result, (o1, o2) -> (o2 + o1).compareTo(o1 + o2))

 

느낀점

  • Array 정렬 방법
    • 단순 정렬시 - Array.sort(arr)
    • 복잡 정렬시 - Arrays.sort(result, (o1, o2) -> (o2 + o1).compareTo(o1 + o2))

 

반응형
반응형

에러 내용

Exception Type - I/O error on POST request for "주소": 주소; nested exception is java.net.UnknownHostException: 주소

=> 해당 호스트 정보 / DNS 등을 찾지 못해 발생

 

상세 내용

몇달동안 실제 운영서버에서 정상적으로 해당 api를 호출되다가, 간헐적으로 해당 에러가 나면서 요청 실패가 나는 상황
(
이틀간 수치가 급증하여, 조치 필요)

로컬에서도 같은 현상 발생 (간헐적으로 실패)

 

 

예상 원인

Java 애플리케이션에서 유효한 DNS정보를 응답받지 못하는 경우

=> Google DNS 서버가 해당 도메인을 제대로 인식하지 못 하거나, 문제가 잠시 생긴것으로 추측

 

해결 ( 1)

1. Hosts 파일 변경

DNS 되는것으로, Hosts에서 ip-DNS 등록해서 사용
=> 로컬에서도 손쉽게 적용가능하고, 재시작(리부팅)이 필요 없음. 단, 상대의 IP가 바뀌면 수동으로 다시 맵핑 시켜줘야 함

방법
vi /etc/hosts
내용 입력(ip,DNS) 127.0.0.1       localhost
(참고 :  ping 도메인 => 실제 ip 조회 가능)

 

2. DNS 설정 변경

주/보조가 모두 구글 서버라 하나를 다른 DNS Server를 바라보도록 변경해서 테스트해본 결과, 정상적으로 요청
=>  vi /etc/resolv.conf (운영체제 / 버전에 따라 다를수 있지만, IP or DNS Server 설정 부분을 찾아서 수정)

DNS1 - 8.8.8.8(Google) -> 1.1.1.1(Cloudflare)
DNS2 - 8.8.4.4(Google) -> 8.8.8.8 (Google)

반응형
반응형

정리하게 된 계기

오늘 DB튜닝을 하다가 실행계획을 보았는데, 제가 알고 있던것과 다른점이 있어

믿보 블로그(기억보단 기록을)의 내용과 이번에 쓰면서 알게 된 점을 정리해봤습니다.

 

그 내용은...

여러개의 컬럼으로 이루어진 복합 인덱스의 컬럼 순서를 지키지 않았는데 인덱스를 타버리네?! 

Index1 : A,B,D
Index2 : C,D
쿼리1 : where A = '조건' and D = '조건' and  B = '조건'
쿼리2 : where C = '조건' and D = 조건''

쿼리 2는 Index2를 타고, 쿼리 1은 Index1과 컬럼 순서가 달라서 당연히 오래걸리겠거니 했는데, 제가 잘못 알고 있었어요.

위처럼 and 조건의 순서가 실제 인덱스와 꼭 같지 않더라도, 실행계획이나, 실제 수행시간이 똑같이 나왔습니다.

컬럼 순서를 지켜야, 인덱스를 탄다고 알고 있었는데, 민망하니까 후딱 찾아봤습니다.

 

인덱스 생성시

○ 카디널리티(중복을 제외하는 수치) 높은 컬럼 사용
○ 인덱스의 생성시 컬럼 순서는 카디널리티가 높음 -> 낮음 순서가 성능이 좋음


인덱스 사용 조회시

○ 인덱스가 여러 컬럼인 경우, 몇몇 조건 생략 가능
(인덱스 컬럼 앞에서 부터 포함하는게 좋음, index-컬럼1,2,3,4 중 3,4 생략가능)
○ 범위 조건 (Between, like, <,>)은 해당 컬럼까지만 인덱스를 타고, 그 뒤로는 인덱스를 타지 않음
○ In, =는 다음 컬럼도 인덱스 사용 (in은 =의 멀티)
○ Or 보다는 and가 성능상 좋음 (or는 row가 늘어나서 풀스캔 가능)
○ 인덱스의 컬럼을 그대로 사용해야 함 (연산 처리를 하지 않고)
○ 예전처럼 인덱스와 컬럼 순서를 반드시 지키지 않아도 인덱스 사용 가능 (컬럼 재배치 과정이 추가 되지만 거의 같음)

 

출처 - 기억보단 기록을

 


실제 사용하면서, 느낀점

  • 시간/날짜를 범위로 많이 검색하는 경우
    인덱스 생성시 시간 컬럼을 뒤쪽에 배치하는게 유리 (인덱스의 최대한 많은 컬럼에 대해 인덱스 사용)
  • 정확한 시간/날짜로 많이 검색하는 경우
    인덱스 생성시 시간 컬럼을 앞쪽에 배치하는게 유리 (시간으로 필터링 = 카디널리티 높음)
  • or , !=, not in 은 비효율적
    or는 row수가 늘어나고, not 이 붙는 연산자는 결국 full-scan을 타게 되는 경우가 대부분이라, 되도록 지양하는게 성능상 유리
  • 인덱스의 컬럼 순서를 지키지 않아도 인덱스 사용 가능 (그래도 이왕이면 지키자)
반응형
반응형

문제 설명

문자열 s의 길이가 4 혹은 6이고, 숫자로만 구성돼있는지 확인해주는 함수, solution을 완성하세요. 예를 들어 s가 "a234"이면 False를 리턴하고 "1234"라면 True를 리턴하면 됩니다.

문제

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

나의 풀이

public class StringExercise {

    public static void main(String[] args) {
        String str = "912345";
        System.out.println("RESULT : "+ solution(str) );
    }

    public static boolean solution(String s) {
        boolean answer = false;
        try {
            if(s.length()==4 || s.length()==6){
                Integer number = Integer.parseInt(s);
                if(number > 0)
                    answer = true;
            }
        }catch (Exception e){ e.printStackTrace(); }
        return answer;
    }
}

접근

별 다른 로직이 필요 없어 보이고, 역시 가장 단순하지만 기본적인 접근으로 시작!
간단한 조건식(if)과 try/catch로 처리가 가능해보여서 작성하다 보니까 완성했는데, Best 풀이라 딱히 언급할건 없어보임

중간에 5,6번과 11번 데이터에 대한 처리가 약간 골치였지만!  음수, 자리수를 잘 처리해주었다.

다른 사람의 풀이

    // 정규식을 활용한 다른 사람의 풀이
    public static boolean solution2(String s) {
        boolean answer = false;
        if(s.length()==4 || s.length()==6){
            String pattern = "^[0-9]*$";
            return s.matches(pattern);
        }
        return answer;
    }

대동소이하나, 보통 정규식의 유무 정도만 다르고 대체로 다른 답도 비슷해 보인다.

느낀점

  • 자주 쓰이는 정규식은 잘 알아두면 항상 편리하니까 정리!
    str.matches("^[0-9]*$")  // 숫자만 있는지 확인
    str.matches("^[a-zA-Z]*$")  // 문자(영어)만 있는지 확인
    str.matches("^[a-zA-Z0-9]*$")  // 문자(영어)+숫자만 있는지 확인
    • matches는 뒤의 정규식이 있는지 boolean으로 결과 반환
    • ^ : 문자열 시작
    • [ ] : 문자의 집합
    • * : 앞문자가 많거나 무제한일수 있음 (*$: 자리수 상관없이 확인할때)
    • $ : 문자열 끝
    • ^[a-zA-Z]*$  : 첫 문자
  • 자주 쓸때는 좀 익숙하다가도, 오랜만에 보니까 정규 표현식이 기억이 안난다.
    https://moonong.tistory.com/31 참고하자!

 

반응형
반응형

문제 설명

자연수 n이 매개변수로 주어집니다. n을 x로 나눈 나머지가 1이 되도록 하는 가장 작은 자연수 x를 return 하도록 solution 함수를 완성해주세요. 답이 항상 존재함은 증명될 수 있습니다.

문제

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

나의 풀이

import java.util.stream.IntStream;

public class NumberOfRemainingOne {

    public static void main(String[] args) {
        int n = 12;
        solution(n);
    }

    public static int solution(int n) {
        int answer = 0;
        while(true){
            if(n % ++answer == 1) break;
        }
        return answer;
    }
}

접근

별 다른 로직이 필요 없어 보이고, 역시 가장 단순하지만 기본적인 접근으로 시작 (시작과 끝 숫자를 잘못 정했지만..)

문제 풀이 컨셉은 다들 비슷했고, 나는 끝을 알수 없기에 while문을 적었으나, answer < n 으로 조건을 걸고, 시작은 2부터 했으면 더욱 깔끔한 코드일듯 하다

다른 사람의 풀이

    // Stream 을 활용한 다른사람의 풀이
    public static int solution(int n) {
        return IntStream.range(2,n).filter(i -> n % i == 1).findFirst().orElse(0);
    }

오늘도 Stream 한스푼! 일단 성능은 차치하고, 쓰는 법이나 익힐겸 적어보았다.
IntStream으로 2부터n까지 범위를 주되, filter로 조건을 걸어서 나머지가 1인 숫자, 그중에 첫번째를 찾는 로직

느낀점

  • 이번 문제는 딱히...없는듯
반응형
반응형

문제 설명

0부터 9까지의 숫자 중 일부가 들어있는 정수 배열 numbers가 매개변수로 주어집니다. numbers에서 찾을 수 없는 0부터 9까지의 숫자를 모두 찾아 더한 수를 return 하도록 solution 함수를 완성해주세요.

문제 보러 가기

 

나의 풀이

import java.util.ArrayList;

public class AddingSomeNumbers {

    public static void main(String[] args) {
        int[] numbers = {1,2,3,4,6,7,8,0};
        solution(numbers);
    }

    public static int solution(int[] numbers) {
        int answer = 0;
        ArrayList<Integer> numbersList = new ArrayList<>();

        for (int number : numbers) {
            numbersList.add(number);
        }
        for(int i = 0; i < 10; i++){
            if(!numbersList.contains(i))
                answer += i;
        }

        return answer;
    }
}

접근

나의 풀이 방법 - Count는 ArrayList의 contains를 활용

그렇다면, 풀어야 할 문제는 2가지 : Array(int[])를 ArrayList로 어떻게 바꿀것인가?

다른 사람의 풀이

// 1 - for 사용하지만, 문제에 대한 깊은 이해로 인해 모두 더한 수를 생각해 냄
class Solution {
    public int solution(int[] numbers) {
        int sum = 45;
        for (int i : numbers) {
            sum -= i;
        }
        return sum;
    }
}

// 2 - 45(모두 더한 수)와 stram 객체를 활용한 방법으로, Stream을 익히는게 좋을듯 
import java.util.Arrays;

class Solution {
    public int solution(int[] numbers) {
        return 45-Arrays.stream(numbers).sum();
    }
}

오랜만에 풀어서 그런지 45를 생각해내지 못했다

게다가 Stream도 익숙지 않아서 생각하지 못해 아쉽다

느낀점

  • Count할 방법을 미리 정해놓으니까, 문제의 접근 방식이 제한돼서 오히려 돌아서 푼 느낌
 
반응형

+ Recent posts