728x90

 

문제는 틈틈히 푸는데 TIL를 쓰기엔 정성이 부족해서 잘안하게 되네요.. ㅎㅎ

 

오늘은 백준 문제 12605번 : 단어순서 뒤집기 에 대해서 이야기 해볼까 합니다.

 

 


문제

스페이스로 띄어쓰기 된 단어들의 리스트가 주어질때, 단어들을 반대 순서로 뒤집어라. 각 라인은 w개의 영단어로 이루어져 있으며, 총 L개의 알파벳을 가진다. 각 행은 알파벳과 스페이스로만 이루어져 있다. 단어 사이에는 하나의 스페이스만 들어간다.

 

입력

첫 행은 N이며, 전체 케이스의 개수이다.
N개의 케이스들이 이어지는데, 각 케이스는 스페이스로 띄어진 단어들이다. 스페이스는 라인의 처음과 끝에는 나타나지 않는다. N과 L은 다음 범위를 가진다.
N = 51 ≤ L ≤ 25

 

 

 

앞서 그냥 받은 문자열을 뒤집는것이 아닌 항해99에서 내준 문제는 스택/큐 를 사용해서 문제를 풀라고 하여서 Stack을 사용했습니다.

 

public class backjoon12605 {
    public static void main(String[] args) throws IOException {
    	//BufferedReader로 입력받기
    	//BufferedReader를 사용해 입력을 받아 n에 저장합니다. n은 테스트 케이스의 수입니다.
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        //for문이 각 테스트 케이스마다 실행됩니다.
        //Stack<String> q = new Stack<>();가 for문 안에 있어, 각 테스트 케이스마다 새로운 Stack이 생성됩니다.
        for(int i =1; i<=n; i++){
            Stack<String> q = new Stack<>();
            //입력된 문장을 split(" ")으로 단어별로 나누어 String 배열 que에 저장합니다.
            String[] que = br.readLine().split(" ");
            //for-each 루프를 사용해 각 단어를 Stack에 push()로 추가합니다.
            for(String a : que){
                q.push(a);
            }
            //System.out.print("Case #" + i + ":");를 출력해 현재 테스트 케이스 번호를 출력합니다.
            //while (!q.isEmpty()) 루프에서 Stack이 비어있지 않을 때까지 pop()을 사용해 단어를 출력합니다. Stack은 LIFO(Last In, First Out) 구조이므로 마지막에 push()된 단어부터 출력되어 단어 순서가 역순이 됩니다.
            //System.out.println();로 각 테스트 케이스 출력을 마치고 줄바꿈을 합니다.
            System.out.print("Case #"+i+": ");
            while(!q.isEmpty()){
                System.out.print(" "+ q.pop());
            }
            System.out.println();
        }

    }
}

 

TIP : 

 

각 테스트 케이스마다 Stack을 새로 생성하므로, 이전 테스트 케이스의 데이터가 현재 테스트 케이스에 영향을 주지 않습니다.
Stack의 내용을 pop()하면서 단어를 출력할 때, 단어가 역순으로 출력됩니다.

stack이 for문 밖에 선언이 되어있어도 잘 작동되고 답변 똑같이 나옵니다. 그러나 그럴 경우,
모든 테스트 케이스가 동일한 Stack 인스턴스를 공유하기 때문에 예상치 못한 결과를 초래할 수 있습니다.
다만, 현재 코드 구조에서는 매 반복문 안에서 Stack 이 비워질 때까지 pop() 을 호출하므로 동작할 수 있습니다.

 

728x90

'잡담' 카테고리의 다른 글

아파치 스톰 과 아파치 카프카  (0) 2024.07.16
JDBC -1  (0) 2022.01.13
API-IO (입출력 성능향상 보조 스트림)  (0) 2021.12.20
Input, Output  (0) 2021.12.20
728x90

안녕하세요, 요즘 야근에 푹 빠져 살고있어서 오랜만에 글을 적습니다.

예전부터 늘  공유하고 싶었던 아파치 스톰과 카프카의 장단점에 대해 적어보도록하겠습니다.

저는 FDS(이상거래방지 시스템) 과 관련된 솔루션 회사에 근무를 하고 있고,

제가 오기전부터 대용량 처리를 위한 파이프라인의 한 축을 카프카 아닌 스톰을 데이터 스트림의 실시간 처리를 위해 채택을 했습니다.

이런식으로 데이터가 오갈때 log 를 수집하기도 하며 룰탐지를 통해서 미리 예방할수도 있습니다. 요즘은 금감원에서 더더욱 책임을 은행에  묻고 있어서  더 견고하게 만들어야하는 경우가 생기고있습니다.

왜 카프카 가 아닌 스톰을 했는지 알지는 못하여서 둘의 차이점을 살펴보면서 왜 도입하게 되었는지 알아보도록하겠습니다.

먼저, 대용량 처리에 필수적인 요소인 아차피 카프카에 대해서 알아보겠습니다.

 

Apache Kafka는 스트림 처리에 사용되는 오픈 소스 도구이며 publish-subscribe model을 기반으로 작동을 합니다.

대량의 데이터를 처리하는데 사용되고 비정형 데이터를 효율적인 방식으로 더 빠르게 처리할 수 있습니다, 또한

데이터 스트림 처리를 위해 소스와 대상 사이의 중개자로 자주 사용됩니다.  

그 외에 데이터를 수집, 처리, 저장 통합하는 데이터 수집, 처리, 통합 플랫폼입니다. (주로 Java 언어와 같이 사용됨)

우리는 카프카의 동작을 이해하려면 "이벤트 스트리밍 플랫폼" 에 대해 이해를 하고 있어야 합니다.

간략하게, 카프카는 수신된 모든 데이터를 디스크에 저장합니다. 그런 다음 데이터가 손실되지 않도록 안전하게 보관하기 위해 카프카 클러스터에 데이터를 복사합니다. 한편, 아파치 카프카에 고유한 메시지 식별자가 없기 때문에 실벽자는 메시지가 전송된 시간만 고려해양합니다.

특정 주제에 대해 누가 읽었는지 또는 특정 메시지를 보았는지도 추적하지 않습니다.

소비자는 이 데이터를 모니터링을 해야하며 데이터를 받을 때는 오프셋만 선택할 수 있습니다.

그러면 해당 오프셋부터 순차적으로 데이터가 변환됩니다.

Apache Storm은 데이터 스트림의 실시간 처리에 사용되는 분산 시스템입니다.

주요 기능은 대량의 데이터를 빠른 속도로 처리하는것에 있고, 중간 규모의 클러스터에서는 노드당 초당 백만개 이상의 레코드를 처리할 수 있습니다.

설정이 쉽고 운영이 간편합니다.또한 확장성과 내결함성 기능을 제공하고 있으며 사용이 간단하고 모든 프로그래밍 언어와 함께 사용할 수 있는 기능을 제공합니다.

공식 사이트에선 아파치 스톰을 사용하면 무제한의 데이터 스트림을 안정적으로 처리할수 있으며, 일괄 처리를 위해 Hadoop이 했던 일을 실시간 처리를 위해 수행 할 수 있다고합니다.

벤치마크에서 노드당 초당 백만 개 이상의 튜플을 처리한 것으로 기록될 정도로 Apache Storm은 빠릅니다. 확장 가능하고, 내결함성이 있으며, 데이터 처리를 보장하고, 설정과 운영이 쉽습니다.

아파치 스톰 아파치 카프카

트위터(현 X) 에서 만듬 linkedin에서 만듬
실시간 메시지 처리 플랫폼 분산 메시지 처리 플랫폼
데이터를 저장하는데 사용되지 않고 데이터를 전송하는 중개자 역할을 한다. 로컬 파일 시스템을 유지하고 데이터를 저장하는 데 사용된다.
외부 종속성을 포함하지 않습니다. 카프카 서버를 실행하기 위해 주키퍼에 대한 종속성을 포함함
보안 기능을 제공합니다. 데이터 보안 기능은 제공하지 않습니다.
스톰이 제공하는 지연 성능은 일반적으로 1-2초 미만입니다. 카프카가 제공하는 레이턴시 성능은 일반적으로 밀리초 단위입니다.
모든 프로그래밍 언어와 함께 사용할 수 있는 기능을 제공합니다. 주로 자바 언어를 함께 사용됩니다.
사용과 운영이 쉽습니다. 확장성 및 내구성 같은 기능이 제공됩니다.
자바와 같은 언어로 사용하여 작성됩니다. 스칼라 및JVM 언어를 사용하여 작성됩니다.

 

위와 같은 스톰의 장점 즉 지연 성능은 일반적으로 1-2초 미만이며 보안기능을 제공함으로써

금융거래에 이상거래방지시스템 과 같이 1초 단위가 중요하고 데이터를 저장하지 않고 이상거래를 탐지해서 데이터를 처리하는 것에 조금 더 적합하다고 생각해서 카프카 대신 아파치 스톰을 도입한것으로 보입니다. 또한, 사용과 운영이 쉬운것이 특징이고, 러닝커브가 카프카에 비해 어렵지 않는 다는 이유로 유지보수에 쉬울것으로 판단해서 도입한것으로 생각이 듭니다.

이 글은 아직 완성이 되지 않았지만 공유를 드리겠습니다.

 

 

스톰을 사용하는 회사 리스트 : Twitter(X), Spofity, infochimps, RocketFuel, Wego 

외국계 대기업들이 주로 사용하고있습니다.

제가 알고 있는 국내 기업은 : 농협은행이 사용하였지만, 2025년 이후로는 카프카로 변경되는걸로 알고있습니다.

728x90

'잡담' 카테고리의 다른 글

TIL(Today I Learned) #3 이야기  (0) 2024.11.09
JDBC -1  (0) 2022.01.13
API-IO (입출력 성능향상 보조 스트림)  (0) 2021.12.20
Input, Output  (0) 2021.12.20
728x90

JDBC(Java Database Connectivity) 프로그래밍

        - JDBC : 자바 프로그램에서 SQL 문을 실행하여 데이터를 관리하기 위한 JAVA API입니다.

 

SQL 문을 실행하기 위한 다양한 방법이 존재합니다.

  • Mybatis (Spring 에서 학습)
  • 하이버네이트 JPA 등이 있습니다.

 

자바가 DB와 통신할수 있게 해주는 API 

 

연결 API connector 가 필요하다.

-MySQL 을 사용한다면 MySQL 용 JDBC를 사용합니다.

-ORACLE 을 사용한다면 오라클 JDBC를 사용합니다.

 

JDBC 라이브러리 추가 위치

 

lib폴더에 넣어주면 됩니다.

 

주요 DBMS 의 JDBC 드라이버 클래스

1.MySQL : "com.mysql.jdbc.Driver"

2. ORACLE: "oracle.jdbc.driver.OracleDriver"

 

주요 DMBS 의 JDBC URL 패턴

1.ORACLE ; "jdbc:oracle:thin:호스트이름:포트번호:DB이름"

2.PDB의 경우 : "jdbc:oracle:thin:호스트이름:포트번호:XEPDB1"

데이터베이스 연결을 위한 Connection 객체

-데이터베이스와 JAVA연결

-DriverManager.getConnection() 메서드를 사용하여 커넥션을 구할수 있습니다.

- 연결이 끝난 뒤에는 반드시 close() 메서드를 호출하여 Connection 객체가 사용한 시스템 자원을 반환해야 합니다.

그렇지 않으면 시스템 자원이 불필요하게 소모되어 커넥션을 구할 수 없는 상황이 발생할 수도 있습니다.

 

쿼리문을 실행하기 위한  Statement 객체

-connection 객체를 생성한 후에는 Connection객체로부터 Statement 를 생성하고 쿼리문을 실행

 

주요 메서드

1.executeQuery() - select 쿼리문을 실행하빈다.

2.executeUpdate() - insert, Update, Delete쿼리문을 실행합니다.

 

쿼리 실행 결과 값을 읽어오는 ResultSet객체-Statement 객체의 executeQuery() 메서드는 Select 쿼리문의 결과를 ResultSet 객체에 담아서 리턴 합니다.

 

ResultSet 주요 메서드1.next() - 다음 값의 확인2.getString() - 지정한 컬럼 값을 String 으로 읽음3.getint() - 지정한 컬럼 값을 int타입으로 읽음4.getDouble()- 지정한 컬럼 값을 double 타입으로 읽음

 

Staement 객체를 대신하는 PreparedStaetement 객체

 

- Statement 객체와 PreparedStatement 객체는 쿼리문을 실행하는 동일한 기능을 제공하빈다.

-PreparedStatement 객체는 값을 지정할 때 값 부분을 물음표(?)로 처리하기 때문에 간단히 값을 지정할수 있습니다.

이때 첫번째 물음표의 인덱스는 1이며, 이후 물음표의 인덱스는 나오는 순서대로 인덱스 값이 1씩 증가합니다.

728x90

'잡담' 카테고리의 다른 글

TIL(Today I Learned) #3 이야기  (0) 2024.11.09
아파치 스톰 과 아파치 카프카  (0) 2024.07.16
API-IO (입출력 성능향상 보조 스트림)  (0) 2021.12.20
Input, Output  (0) 2021.12.20
728x90

입출력 성능향상 스트림 BufferedWriter

 

이클래스는 텍스트 파일을 프로그램으로 읽을때 사용하는 문자 기반 스트림입니다.

데이터를 읽고 버퍼에 저장하나 후 한번에 쓰는 형태로 사용되기 때문에 속도가 빠릅니다.

주요 메서드

-write 클래스와 거의 동일

flush() : 버퍼를 비운다.

주의할점

버퍼가 가득찼을 때만 출력을 해내기 때문에 flush() 를 호출하여 잔류하는 데이터를 모두 보내야합니다.

 

입출력 성능향상 스트림 BufferedReader

이 클래스는 텍스트 파일을 프로그램으로 읽을때 사용하는 문자 기반 스트림입니다.

데이터를 읽고 버퍼에 저장한 후 한번에 읽는 형태로 사용되기 때문에 속도가 빠릅니다.

주요 메서드

Reader클래스와 거의 동일

readLine() :한줄을 한꺼번에 읽어 들입니다.

728x90

'잡담' 카테고리의 다른 글

TIL(Today I Learned) #3 이야기  (0) 2024.11.09
아파치 스톰 과 아파치 카프카  (0) 2024.07.16
JDBC -1  (0) 2022.01.13
Input, Output  (0) 2021.12.20
728x90

input 과 output에 대해서 공부하였습니다 .

API IO (input 스트림, output스트림)

입력과 출력을 담당하는 스트림으로 구성된 클래스입니다.

스트림은 테이터의 흐름(흐름의 통로)를 말합니다.

키보드와 마우스를 연결하면 자동으로 스트림이 지나다니는통로가 생성이 됩니다.

 

스트림클래스는 두가지로 나뉩니다. 

 

사진으로 보시는거와 같이 빨간줄에 있는것들이 가장 흔히 쓰이고 중요한클래스라고 보시면 됩니다.

OutputStream 클래스

-1바이트 개념으로 쓰는 최상위 클래스로 추상 클래스입니다.

IO 패키지의 모든 클래스는 생성자에 throws 키워드가 있기 때문에 try~ catch 문과 함께 써야합니다.

 

 

 

먼저 스캐너로 입력받을값을 준비해줍니다. 

파일경로를 지정하는 트라이 캐치 구문안에 파일경로를 지정합니다.

try 구문을 쓸때는 최종적으로 클로스 를 선언해야하는데 그냥 선언을 하기 되면 

에러가 발생합니다.

에러를 처리하기 위해서는 FileOutputStream을 구문 밖에다가 선언을 해줘야 합니다.

FileOutputStream fos = null; 이라고 선언해주고 

트라이 구문안에는 fos = new FileOutputStream("경로..) 선언합니다

finally 안에 fos.close()를 선언하고 try~catch구문을 실행해줍니다.

scan.next()를 받아서 next()안에 엔터값을 제가해주고 

String str = Scan.nextLine()을 다시 받아 값을 적어줍니다.

byte배열안에 string str.getbyte문자열의 바이트데이터를 얻습니다.

파일을 바이트 단위로 내려가면 쓰입니다.

fos.write(arr) 지정경로를 정해줍니다.

 

InputStream - 바이트 단위로 읽는 클래스

1바이트 단위로 읽어서 가져오기 때문에 한글자밖에 안가져옵니다. 한글은 2바이트가 기본이기때문에

읽는데 깨져서 오기때문에 쓰임세는 읽기보단 이미지, 동영상 등에 쓰입니다.

1바이트 단위로 인해 글자를 하나씩 밖에 못가져와 while 반복문을 통해 문장을 가져올수있습니다.

그리고 데이터에서 더이상 읽을 데이터가 없다면 -1을 반환합니다.그렇지 않으면 무한적으로 -1이 돌아갑니다.

주요 메서드는 

read(); - 1바이트씩 읽어주는 바이트

read(byte[] b) - 매개값을 바이트로 받는다.

 

대표적 매서드

write(byte b) - 출력 스트림으로 1바이트를 내보냄

매개변수로는 바이트 배열 아니면 바이트 한글자 사용가능.

 

 

 

 

 

728x90

'잡담' 카테고리의 다른 글

TIL(Today I Learned) #3 이야기  (0) 2024.11.09
아파치 스톰 과 아파치 카프카  (0) 2024.07.16
JDBC -1  (0) 2022.01.13
API-IO (입출력 성능향상 보조 스트림)  (0) 2021.12.20

+ Recent posts