2021년 4월 23일 금요일

[ Scala ] 스칼라 프로젝트 Remote Git 환경설정

잘 설명되어있는 참조URL : 

 https://atoz-develop.tistory.com/entry/IntelliJ%EC%97%90%EC%84%9C-GitGitHub-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0-%EA%B8%B0%EC%A1%B4-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%97%B0%EB%8F%99%ED%95%98%EA%B8%B0

[ Scala ] Case Class에 대하여

 

스칼라는 케이스 클래스 개념을 지원하는데 특징은 아래와 같다.

  • 불변
  • 패턴매칭을 통해 분해가능
  • 레퍼런스가 아닌 구조적인 동등성으로 비교
  • 초기화와 운영이 간결


예제

Notification.scala이라는 case class스칼라 파일을 생성

abstract class Notification
case class Email(sourceEmail: String, title: String, body: String) extends Notifica
case class SMS(sourceNumber: String, message: String) extends Notification
case class VoiceRecording(contactName: String, link: String) extends Notification


클래스 Email, SMS, VoiceRecording은 일반적인 클래스와 다르다.

1. 

인스턴스를 생성할 때 NEW 키워드 생략가능. 

Ex)

val emailFromJohn = Email("doe@mail.com", "Greetings!", "Hello World!")


2. 

생성자 파라미터들에 대한 getter함수가 자동으로 정의. 

public값으로 다뤄지며 직접 접근가능 

Ex)

val title = emailFromJohn.title println(title) // prints "Greetings From John!"


3.

케이스클래스 필드 수정 불가능

Ex)

emailFromJohn.title = "Goodbye From John!"

// 컴파일시에 에러가 난다. 모든 케이스 클래스 필드는 기본적으로 val이다.

// var을 사용하여 변경할 수 있지만, 권장하지 않는다.


4.

클래스 복사가 가능하며 필드값을 대체할 수도 있다.

Ex)

val editedEmail =
emailFromJohn.copy(title = "I am learning Scala!", body = "It's so cool!")

println(emailFromJohn)
// prints "Email(john.doe@mail.com,Greetings From John!,Hello World)"

println(editedEmail)
// prints "Email(john.doe@mail.com,I am learning Scala,It's so cool!)"


5.

모든 케이스클래스에 대해 equals 메서드와 toString메서드를 생성

Ex)

val firstSms = SMS("12345", "Hello!") val secondSms = SMS("12345", "Hello!") if (firstSms == secondSms) { println("They are equal!") } println("SMS is: " + firstSms)


6.

케이스클래스를 통해 데이터와 함께 동작하는 패턴매칭 사용가능

object Test {

def showNotification(notification: Notification): String = {
notification match {
case Email(email, title, _) =>
"You got an email from " + email + " with title: " + title
case SMS(number, message) =>
"You got an SMS from " + number + "! Message: " + message
case VoiceRecording(name, link) =>
"you received a Voice Recording from " + name + "! Click the link to hear it: " + link
}
}

def main(args: Array[String]): Unit = {
val someSms = SMS("12345", "Are you there?")
val someVoiceRecording = VoiceRecording("Tom", "voicerecording.org/id/123")

println(showNotification(someSms))
println(showNotification(someVoiceRecording))
}
}


// prints: // You got an SMS from 12345! Message: Are you there? // you received a Voice Recording from Tom! Click the link to hear it: voicerecording.org/id/123


7.

패턴매칭 if를 통한 다른 예제

object Test {

def showNotification(notification: Notification): String = {
notification match {
case Email(email, title, _) =>
"You got an email from " + email + " with title: " + title
case SMS(number, message) =>
"You got an SMS from " + number + "! Message: " + message
case VoiceRecording(name, link) =>
"you received a Voice Recording from " + name + "! Click the link to hear it: " + link
}
}

def showNotificationSpecial(notification: Notification, specialEmail: String, specialNumber: String): String = {
notification match {
case Email(email, _, _) if email == specialEmail =>
"You got an email from special someone!"
case SMS(number, _) if number == specialNumber =>
"You got an SMS from special someone!"
case other =>
showNotification(other) // nothing special, delegate to our original showNotification function
}
}

def main(args: Array[String]): Unit = {
val SPECIAL_NUMBER = "55555"
val SPECIAL_EMAIL = "jane@mail.com"
val someSms = SMS("12345", "Are you there?")
val someVoiceRecording = VoiceRecording("Tom", "voicerecording.org/id/123")
val specialEmail = Email("jane@mail.com", "Drinks tonight?", "I'm free after 5!")
val specialSms = SMS("55555", "I'm here! Where are you?")

println(showNotificationSpecial(someSms, SPECIAL_EMAIL, SPECIAL_NUMBER))
println(showNotificationSpecial(someVoiceRecording, SPECIAL_EMAIL, SPECIAL_NUMBER))
println(showNotificationSpecial(specialEmail, SPECIAL_EMAIL, SPECIAL_NUMBER))
println(showNotificationSpecial(specialSms, SPECIAL_EMAIL, SPECIAL_NUMBER))
}
}



참조 : 

https://docs.scala-lang.org/ko/tutorials/scala-for-java-programmers.html

https://docs.scala-lang.org/ko/tour/case-classes.html

2021년 4월 19일 월요일

[ Spark ] Mysql 연결 후 DATA SELECT

 

[ Mysql연결 후 데이터 Select ]


접속정보를 option으로 주는 방법과

java.util.properties객체를 이용해

Mysql Server와 연결하는 방법이있다.


import org.apache.spark.SparkConf
import org.apache.spark.sql.SparkSession
import java.util.Properties

object RdbToHive {
def main(args: Array[String]): Unit = {
val conf = new SparkConf()
.setAppName("SELECT RDBMS DATA")
.setMaster("local")

val spark = SparkSession.builder.config(conf).getOrCreate()

// Loading data from a JDBC source
val jdbcDF = spark.read
.format("jdbc")
.option("url", "jdbc:mysql://dbserver:3306")
.option("dbtable", "test_db.tmp_table")
.option("user", "admin")
.option("password", "e123123")
.load()
jdbcDF.show(10)

// Loading data from a JDBC source2
val connectionProperties = new Properties()
connectionProperties.put("user", "admin")
connectionProperties.put("password", "e123123")
val jdbcDF2 = spark.read
.jdbc("jdbc:mysql://dbserver:3306", "test_db.tmp_table", connectionProperties)
jdbcDF2.show(10)

}
}



참조 : 

https://spark.apache.org/docs/latest/sql-data-sources-jdbc.html

2021년 4월 17일 토요일

[ Algorithm Java ] 소수만들기

 

문제 ]

문제 설명

주어진 숫자 중 3개의 수를 더했을 때 소수가 되는 경우의 개수를 구하려고 합니다. 

숫자들이 들어있는 배열 nums가 매개변수로 주어질 때, 

nums에 있는 숫자들 중 서로 다른 3개를 골라 더했을 때 

소수가 되는 경우의 개수를 return 하도록 solution 함수를 완성해주세요.


제한사항

nums에 들어있는 숫자의 개수는 3개 이상 50개 이하입니다.

nums의 각 원소는 1 이상 1,000 이하의 자연수이며, 중복된 숫자가 들어있지 않습니다.      


numsresult
[1,2,3,4]1
[1,2,7,6,4]4



제출 ]

class Solution {

    public int solution(int[] nums) {

        int answer = 0;

        int sum = 0;

       

        for(int i=0; i<nums.length-2; i++){

            for(int j=i+1; j<nums.length-1;j++){

                for(int k=j+1; k<nums.length; k++){


                    //3개 더한 값이 소수 인지 판별

                    sum = nums[i]+nums[j]+nums[k];

                    int s = 2;

                    for(; s<sum;s++){

                        if(sum%s==0) break;    

                    }


                    //소수라면 answer에 +1

                    if(s==sum) answer+=1;      

                }

            }

        }


        return answer;

    }

}



풀이 ]

반복문을 도는 변수3개로 3가지 수를 더하는 경우의 수를 구현하고,

더한 수의 값이 소수인지 아닌지 판단



2021년 4월 14일 수요일

[ Practice Scala ] 재귀함수 (Evaluating e^x)


문제 ]

The series expansion of  is given by:

 

Evaluate  for given values of  by using the above expansion for the first  terms.

Input Format

The first line contains an integer , the number of test cases.
 lines follow. Each line contains a value of  for which you need to output the value of  using the above series expansion. These input values have exactly  decimal places each.

Output Format

Output  lines, each containing the value of , computed by your program.

Constraints



VarVal in Scala and def and defn in Clojure are blocked keywords. The challenge is to accomplish this without either mutable state or direct declaration of local variables.

Sample Input

4
20.0000
5.0000
0.5000
-0.5000

Sample Output

2423600.1887
143.6895
1.6487
0.6065


제출 ]

import java.io._
import java.math._
import java.security._
import java.text._
import java.util._
import java.util.concurrent._
import java.util.function._
import java.util.regex._
import java.util.stream._

object Solution {

    def f(x: Double): Double ={
      f2(x, 9)
    }
 
    def fact(x: Int): Int = if (x <= 11 else x * fact(x - 1)
 
    def f2(x: Double, i: Int): Double = {
      if (i == 01 else Math.pow(x, i) / fact(i) + f2(x, i - 1)
    }

    def main(args: Array[String]) {
        val stdin = scala.io.StdIn

        val n = stdin.readLine.trim.toInt

        for (nItr <- 1 to n) {
            val x = stdin.readLine.trim.toDouble
            println(f(x))
        }
    }
}


풀이 ]
x제곱/i!에 대한 재귀, i팩토리얼에 대한 재귀함수



2021년 4월 12일 월요일

[ Spark ] 파티션과 셔플과의 관계

Executor Memory에 따른 셔플단계에서 파티션 갯수 구하기

https://jaemunbro.medium.com/apache-spark-partition-%EA%B0%9C%EC%88%98%EC%99%80-%ED%81%AC%EA%B8%B0-%EC%A0%95%ED%95%98%EA%B8%B0-3a790bd4675d


Spark 최적화 튜닝관련

https://nephtyws.github.io/data/spark-optimization-part-1/

2021년 4월 8일 목요일

[ Hive ] Oozie와 Sqoop을 통해 가져온 데이터시간 RDB!=HIVE 불일치시

  

[ 파이프라인 ]

Oozie -> Sqoop -> Hive


[ 문제 ]

RDB의 타임존이 UTC라 한국시간보다 9시간 느리다.

그래서 Oozie XML에서 Sqoop Query작성을 아래와 같이

  • SELECT convert_tz('${created_date} 00:00:00', '+00:00', '+09:00') as DATE FROM ...

시간을 +9하여 한국시간에 맞춰 가져온다면

Hive에서는 +9시간 더 더해져 가져오는 경우가 있다.


날짜로 파티션을 하는 하이브테이블일 경우 날짜자체가 달라져

데이터 정합성에 오류가 일어날 수 있다.

  • RDB 시간 : 2021-04-07 14:00:00 (UTC)
  • 예상한 HIVE 시간 : 2021-04-07 23:00:00 (KST)
  • 결과 HIVE 시간 : 2021-04-08 08:00:00


[ 해결 ]

Ooize Scheduler의 시간을 서울로 지정했다면

Sqoop실행시 연결된 RDB의 시간을 비교하여

자동적으로 한국시간에 맞게 +9시간을 해준다.































따라서 Sqoop쿼리에서 convert_tz를 사용하지 않고 쿼리를 작성한다.

Sqoop쿼리의 Where절과는 상관없다. 

최종결과 아웃풋이 나오고 SELECT된 컬럼(DATE관련 타입)들에게 Oozie시간대에 맞게 조정하기 때문이다.