tonglin0325的个人主页

Java适配器设计模式

适配器设计模式,一个接口首先被一个抽象类先实现(此抽象类通常称为适配器类,比如下面的WindowAdapter),并在此抽象类中实现若干方法(但是这个抽象类中的方法体是空的),则以后的子类直接继承此抽象类,就可以有选择地覆写所需要的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
interface Window{					//定义Window接口,表示窗口操作
public void open(); //窗口打开
public void close(); //窗口关闭
public void activated(); //窗口活动
public void iconified(); //窗口最小化
public void deiconified(); //窗口恢复大小
}

abstract class WindowAdapter implements Window{ //定义抽象类实现接口,在此类中覆写方法,但是所有的方法体为空
public void open() {} //窗口打开
public void close() {}; //窗口关闭
public void activated() {}; //窗口活动
public void iconified() {}; //窗口最小化
public void deiconified() {}; //窗口恢复大小
}

class WindowImp1 extends WindowAdapter{ //子类直接继承WindowAdapter类,有选择地实现需要的方法
public void open() { //窗口打开
System.out.println("窗口打开");
}

public void close() { //窗口关闭
System.out.println("窗口关闭");
}
}

public class Adapter_demo {

public static void main(String[] args) {
// TODO 自动生成的方法存根
Window win = new WindowImp1(); //实现接口对象
win.open();
win.close();
}

}

 

Java自定义异常类

用户可以根据自己的需要定义自己的异常类,定义异常类只需要继承Exception类即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class MyException extends Exception{		//自定义异常类,继承Exception类
public MyException(String msg){ //构造方法接受异常信息
super(msg); //调用父类中的构造方法
}
}


//主类
//Function : MyException_demo
public class MyException_demo {

public static void main(String[] args) {
// TODO 自动生成的方法存根
try{
throw new MyException("自定义异常"); //抛出异常
}catch(Exception e){ //异常处理
System.out.println(e);
}

}

}

 

k8s学习笔记——基本命令

  1. 进入pod,获取一个交互 TTY 并运行 /bin/bash
1
2
kubectl exec -it <pod-name> -n <namespace> bash

参考:k8s 命令操作

2.创建namespace

1
2
kubectl create ns xxxx

3.查看所有namespace下的pod

1
2
kubectl get pod -A

查看特定namespace下的pod

1
2
kubectl get pod -n kube-system

查看所有的namespace

全文 >>

mac安装多个版本python

1.安装pyenv

1
2
brew install pyenv

2.是否安装成功

1
2
3
pyenv -v
pyenv 2.0.6

3.安装python3.8.10,2.7.15和miniconda3-4.7.12

1
2
3
4
pyenv install 3.8.10
pyenv install 2.7.15
pyenv install miniconda3-4.7.12

查看可以安装的版本列表

1
2
pyenv install --list

4.查看安装的python版本

1
2
3
4
5
6
7
8
pyenv versions

system
2.7.15
3.7.10
* 3.8.10 (set by /Users/lintong/.python-version)
miniconda3-4.7.12

全文 >>

使用Impala parser解析SQL

Impala对于hive引擎的语法和hive原生的有些许不同,虽然使用hive的parser也能部分兼容,但是由于impala的parser是使用flex(Fast Lexical Analyzer Generator,快速词法分析生成器)和java cup(Java Constructor of Useful Parsers,生成语法分析器(parser)的工具)开发的,所以对impala的query进行语法解析的时候建议还是使用Impala原生的parser

1.在安装了impala的机器下找到impala-frontend的jar包(环境中的impala版本为2.12.0+cdh5.15.1+0)

1
2
3
lintong@master:/opt/cloudera/parcels/CDH/jars$ ls | grep impala-frontend
impala-frontend-0.1-SNAPSHOT.jar

2.使用mvn install安装到本地仓库中,或者上传到私服仓库中

1
2
mvn install:install-file -Dfile=/home/lintong/下载/impala-frontend-0.1-SNAPSHOT.jar -DgroupId=org.apache.impala -DartifactId=impala-frontend -Dversion=0.1-SNAPSHOT -Dpackaging=jar

3.在工程中引入impala-frontend和java-cup,java-cup的版本可以使用反编译工具打开impala-frontend的jar进行确认

1
2
3
4
5
6
7
8
9
10
11
<dependency>
<groupId>org.apache.impala</groupId>
<artifactId>impala-frontend</artifactId>
<version>0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>net.sourceforge.czt.dev</groupId>
<artifactId>java-cup</artifactId>
<version>0.11-a-czt02-cdh</version>
</dependency>

在解析select语句的时候如果报

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
java.lang.NoClassDefFoundError: org/apache/sentry/core/model/db/DBModelAction

at org.apache.impala.analysis.TableRef.<init>(TableRef.java:138)
at org.apache.impala.analysis.CUP$SqlParser$actions.case421(SqlParser.java:18035)
at org.apache.impala.analysis.CUP$SqlParser$actions.CUP$SqlParser$do_action(SqlParser.java:5976)
at org.apache.impala.analysis.SqlParser.do_action(SqlParser.java:1349)
at java_cup.runtime.lr_parser.parse(lr_parser.java:587)
at com.xxxx.xx.core.parser.XXXXTest.getLineageInfo(XXXXTest.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
Caused by: java.lang.ClassNotFoundException: org.apache.sentry.core.model.db.DBModelAction
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 28 more


Process finished with exit code 255

在pom中添加

全文 >>

Java对象的多态性(转型)

多态性在面向对象中主要有两种体现:

<1>方法的重载与覆写

<2>对象的多态性

向上转型:子类对象–>父类对象,向上转型会自动完成

向下转型:父类对象–>子类对象,向下转型时,必须明确地指明转型的子类类型

 

对象的向上转型

虽然使用的父类对象调用fun1方法,但是实际上调用的方法是被子类覆写过的方法,也就是说,如果对象发生了向上转型关系后,所调用的方法一定是被子类覆写过的方法。

但是父类的a无法调用b类中的fun3方法,因为这个方法只在子类中定义,而没有在父类中定义。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class C_1{												// 定义接口C_1
public void fun1(){ //定义fun1()方法
System.out.println("C_1--->public void fun1");
}

public void fun2(){ //定义fun2()方法
this.fun1();
}
}

class D_1 extends C_1{ //子类D_1继承父类C_1
public void fun1(){
System.out.println("D_1--->public void fun1"); //覆写父类中的fun1()方法
}

public void fun3(){
System.out.println("D_1--->public void fun3"); //子类自己定义方法
}
}

// 对象的多态性,对象向上转型
public class ploy_up_demo {

public static void main(String[] args) {
// TODO 自动生成的方法存根
D_1 b = new D_1(); //定义子类的实例化对象
C_1 a = b; //声明一个父类,发生向上转型的关系,子类赋值给父类
a.fun1(); //此方法被子类覆写过,虽然a是父类,但是调用的是子类的fun1()方法
}

}

 

对象的向下转型

在子类中调用了父类中的fun2方法,fun2方法要调用fun1方法,但是此时fun1方法已经被子类覆写过了,所以调用fun2方法的时候还是调用被子类覆写过的方法

在进行对象的向下转型之前,必须首先发生对象的向上转型,否则将出现对象转换异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class C_1{												// 定义接口C_1
public void fun1(){ //定义fun1()方法
System.out.println("C_1--->public void fun1");
}

public void fun2(){ //定义fun2()方法
this.fun1();
}
}

class D_1 extends C_1{ //子类D_1继承父类C_1
public void fun1(){
System.out.println("D_1--->public void fun1"); //覆写父类中的fun1()方法
}

public void fun3(){
System.out.println("D_1--->public void fun3"); //子类自己定义方法
}
}

// 对象的多态性,对象向上转型
public class ploy_up_demo {

public static void main(String[] args) {
// TODO 自动生成的方法存根
// D_1 b = new D_1(); //定义子类的实例化对象
// C_1 a = b; //声明一个父类,发生向上转型的关系,子类赋值给父类
// a.fun1(); //此方法被子类覆写过,虽然a是父类,但是调用的是子类的fun1()方法

C_1 c = new D_1(); //声明一个父类,发生了向上转型,子类赋值给父类
D_1 d = (D_1)c; //声明的父类强制转换成子类,发生了向下转型关系
d.fun1();
d.fun2();
d.fun3();
}

}

全文 >>

airflow学习笔记——operator

operator用于产生特定的DAG节点

1
2
https://airflow.apache.org/docs/apache-airflow/stable/python-api-ref.html#operators

 

下面是常用的operator及其用法

BaseOperator

1
2
https://airflow.apache.org/docs/apache-airflow/stable/_modules/airflow/models/baseoperator.html

用法:

 

BaseSensorOperator

1
2
https://airflow.apache.org/docs/apache-airflow/stable/_modules/airflow/sensors/base.html#BaseSensorOperator.poke

用法:

 

全文 >>

airflow学习笔记——sensor

sensor也是airflow的一种operator,用于检测某个条件是否达到。如果条件满足,sensor将会执行成功;如果条件不满足,sensor将会重试,直到超时,task超时的时候状态就位skipped。

下面是常用的几种sensor:

  • The FileSensor: Waits for a file or folder to land in a filesystem.
  • The S3KeySensor: Waits for a key to be present in a S3 bucket.
  • The SqlSensor: Runs a sql statement repeatedly until a criteria is met.
  • The HivePartitionSensor: Waits for a partition to show up in Hive.
  • The ExternalTaskSensor: Waits for a different DAG or a task in a different DAG to complete for a specific execution date. (Pretty useful that one 🤓 )
  • The DateTimeSensor: Waits until the specified datetime (Useful to add some delay to your DAGs)
  • The TimeDeltaSensor: Waits for a timedelta after the task’s execution_date + schedule interval (Looks similar to the previous one no?)

参考:Airflow Sensors : What you need to know

以及 How Airbnb Built “Wall” to prevent data bugs

 

Java数据结构——红黑树

二叉树:查找时间复杂度:最好:O(lgn),最差O(n)。最差情况是所有的数据全部在一端时。

二叉搜索树(二叉排序树、二叉查找树):查找时间复杂度:最好:O(lgn),最差O(n)。最差情况是所有的数据全部在一端时。

平衡二叉树:查找时间复杂度:O(lgn)

红黑树:查找删除插入时间复杂度:O(lgn)  红黑树是一种自平衡的二叉排序树,它是复杂的,但它的操作有着良好的最坏情况运行时间,并且在实践中是高效的: 它可以在O(logn)时间内做查找,插入和删除,这里的n是树中元素的数目。

 

红黑树(一棵自平衡的排序二叉树)五大特性:

1)每个结点要么是红的,要么是黑的。 

2)根结点是黑的。 

3)每个叶结点,即空结点是黑的。 

4)如果一个结点是红的,那么它的俩个儿子都是黑的。 

5)对每个结点,从该结点到其子孙结点的所有路径上包含相同数目的黑结点。

 

场景

全文 >>