千万级数据拆分与迁移

​ 将数据从一张表中迁移到另一张表中,在数据量少的情况下很容易实现,而且方法也有很多,但当数据量到了百万、千万级时,不同方法在效率上会有很大差别。

阅读更多

面试题

​ 在笔试中经常会遇到很多需要手写代码的题,如果能完整的写出来最好,但如果不习惯手写或时间不够,可已选择写伪码,主要描述清楚关键的实现步骤。

笔试

  1. 写出Collection接口的实现

    Collection
    ├List
    │├LinkedList
    │├ArrayList
    │└Vector
    │ └Stack
    └Set
    Map
    ├Hashtable
    ├HashMap
    └WeakHashMap

  2. 运行时获取class的磁盘路径

    1
    <YOUR CLASS>.class.getProtectionDomain().getCodeSource().getSource().getLocation()
  3. Java多态的表现形式,代码如何实现

    重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现;不同的对象调用同一个方法的到不同的结果。

    1. 继承父类

    2. 重写父类方法

    3. 向上转型

  4. 在工作中遇到或使用过的设计模式,手写实现一个设计模式(除了单例模式)

    Factory(工厂模式), Builder(建造模式), Factory Method(工厂方法模式),
    Prototype(原始模型模式),Singleton(单例模式), Facade(门面模式),
    Adapter(适配器模式), Bridge(桥梁模式), Composite(合成模式),
    Decorator(装饰模式), Flyweight(享元模式), Proxy(代理模式),
    Command(命令模式), Interpreter(解释器模式), Visitor(访问者模式),
    Iterator(迭代子模式), Mediator(调停者模式), Memento(备忘录模式),
    Observer(观察者模式), State(状态模式), Strategy(策略模式),
    Template Method(模板方法模式), Chain Of Responsibleity(责任链模式)
    工厂模式:工厂模式是一种经常被使用到的模式,根据工厂模式实现的类可以根据提供的数据生成一组类中某一个类的实例,通常这一组类有一个公共的抽象父类并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作。首先需要定义一个基类,该类的子类通过不同的方法实现了基类中的方法。然后需要定义一个工厂类,工厂类可以根据条件生成不同的子类实例。当得到子类的实例后,开发人员可以调用基类中的方法而不必考虑到底返回的是哪一个子类的实例。具体实现代码

  5. 手写代码,实现多线程对一整型对象递增,且数值不重复

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public class Test {
    private static int num = 1;
    public static void main(String[] args) {
    Test test = new Test();
    Increasing inc = test.new Increasing();
    for (int i=0;i<=10;i++){
    Thread thread=new Thread(inc);
    thread.start();
    }
    }

    private synchronized void add(){
    num+=1;
    System.out.println(num);
    }

    class Increasing implements Runnable{
    public void run(){
    for(int i=0;i<20;i++){
    add();
    }
    }
    }
    }
  6. 快速获得数组int[] a = {1,2, 3, 5, 6, 12, 4, 7, 14, 9, 8}中第二大的数,写出关键代码

    下面代码的时间复杂度为O(n),不一定是最快的,但只需遍历一次

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public static int getSecondMax(int[] a) {
    int max = a[0];
    int second = a[a.length - 1];
    for (int i = 0; i < a.length; i++) {
    if (a[i] > max) {
    second = max;
    max = a[i];
    } else if (a[i] > second && a[i] < max) {
    second = a[i];
    }
    }
    return second;
    }
  7. 进程和线程的区别和联系?

    进程 - 操作系统分配内存的基本单位 - 一个进程可以包含一个或多个线程
    线程 - 操作系统分配CPU的基本单位

面试

  1. 在之前项目中遇到什么问题,怎么解决。
  2. mysql分页语句。
  3. 线程同步有哪几种方式。
  4. eclipse的中查找类被调用的快捷键是什么。

使用微信测试账号实现web端扫码登录

一般网站应用使用微信扫码登录使用的是微信开放平台的接口,但注册开放平台需要提供企业信息,而且开放平台并没有提供测试账号,个人想要直接通过开放平台实现微信授权登录是不可行的。

微信在公众号中提供了测试账号,我们可以通过公众号实现微信授权;

阅读更多

Activiti6.0流程模型导入

Activiti是一个开源的工作流程引擎,而在流程引擎上执行的便是符合BPMN2.0规范的流程模型。在我们系统集成Activiti后,自然需要提供流程模型的导入功能。

阅读更多

IDEA中的快捷键

IDEA最近更新到了2021.1版,我也下载下来玩下;平时也会使用其中一些快捷键,今天整理记录下;

阅读更多

IDEA中自定义骨架(archetype)

IDEA中可以使用archetype快速生成一个项目骨架,但自带的archetype太精简了,并不一定合适我们,我们可以自定义一个合适我们的骨架。

阅读更多

Python3与Java的简单对比之面向对象

类(class)是构造对象的模板或蓝图。由类构造(construct)对象的过程称为创建类的实例(instance)。

Java核心技术

类提供了一种组合数据和功能的方法。创建一个新类意味着创建一个新类型的对象,从而允许创建一个该类型的新实例。

Python3.7.4文档

在对于类的定义上,Python3与Java定义一致。

​ 下面分别用Java和Python3编写一个People类。

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/**
* People
*/
public class People {
//实例域(成员变量)
private String name;
private int age;
private String gender;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getGender() {
return gender;
}

public void setGender(String gender) {
this.gender = gender;
}

//无参构造器
public People() {
System.out.println("【JPeople】无参构造器");
}

//带参构造器
public People(String name, int age, String gender) {
System.out.println("【JPeople】带参构造器");
this.name = name;
this.age = age;
this.gender = gender;
}

//静态方法
public static void f() {
System.out.println("【JPeople】静态方法");
}

//实例方法
public void sayHello() {
System.out.println("【JPeople】"+this.name + " say:\"Hello\"");
pf();
}

//私有方法
private void pf(){
System.out.println("【JPeople】私有方法");
}
}

public class PeopleTest {
public static void main(String[] args) {
People tom = new People("tom", 18, "male");
tom.sayHello();
People.f();
}
}

​ Java执行结果

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
class People:
"""People"""
# 私有属性
__gift = 100
# 类属性
name = ''
age = 0

# 限定对象只能绑定_gender属性
# __slots__=('_gender')

# 实例化方法
def __init__(self, name, age, gender):
print("【PPeople】构造方法")
self.name = name
self.age = age
self._gender = gender

# getter方法
@property
def gender(self):
return self._gender

# setter方法
@gender.setter
def gender(self,gender):
self._gender=gender

# 静态方法
@staticmethod
def sf():
print("【PPeople】静态方法")

# 类方法
@classmethod
def cf(cls):
print("【PPeople】类方法")

# 实例方法
def say_hello(self):
print("【PPeople】{} say:\"Hello!\",gift={}".format(self.name, self.__gift))
self.__pf()

# 私有方法
def __pf(self):
print("【PPeople】私有方法")

People.age += 1
print(People.age)
People.sf()
tom = People('Tom', 18, 'male')
tom.gender="female"
print(tom.gender)
tom.say_hello()

​ Python执行结果

小结

Java Python
私有属性 (成员变量)使用private关键字修饰 属性名双下划线开头__;不建议将属性设置为私有,建议以_(单下划线)开头,暗示属性为受保护的,不建议外部直接访问,建议使用getter、setter进行操作
类属性 使用static修饰的变量 类和对象都可以访问
构造方法 有参、无参构造器;方法名与类名相同 (实例化方法)方法名固定__init__
实例方法 对象访问 (普通方法)对象访问,默认有参self
私有方法 使用private关键字修饰 方法名双下划线开头__
静态方法 使用static关键字修饰 使用@staticmethod装饰器,可以无参
类方法 同静态方法 使用@classmethod装饰器,类和对象访问,默认参数cls

继承

​ 在Java中类只能单继承继承,因为Java的设计者认为,多继承会让语言本身变得非常复杂(如同C++),效率也会降低(如同Eiffrl),而为了让程序设计更加灵活,Java中就有了接口(interface),接口之间可以多继承。而Python的类可以多继承,也就没必要有接口;下面分别使用Java和Python 3实现Student子类

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
public class Student extends People{

//学号
private String studentNumber;

public String getStudentNumber() {
return studentNumber;
}

public void setStudentNumber(String studentNumber) {
this.studentNumber = studentNumber;
}
//子类无参构造器
public Student() {

}
//带参构造器
public Student(String name, int age, String gender, String studentNumber) {
//调用父类带参构造器
super(name, age, gender);
System.out.println("【JStudent】带参构造器");
this.studentNumber = studentNumber;
}

//重写父类方法
public void sayHello(){
System.out.println("【JStudent】"+this.getName() + " say:\"Hello\"");
}

public static void main(String[] args) {
Student student_1 = new Student("Jerry", 17, "male", "0021");
student_1.sayHello();
}
}

​ Java执行结果

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
41
42
43
# 单继承
class Student(People):
# 子类构造方法
def __init__(self, name, age, gender, student_number):
print("【PStudent】构造方法--开始")
# 调用超类构造方法
super(Student, self).__init__(name, age, gender)
self.student_number = student_number
print("【PStudent】构造方法--结束")

# 重写父类方法
def say_hello(self):
print("【PStudent】{} say:\"Hello!\"".format(self.name))

# Child类,为多继承做准备
class Child:
def __init__(self, name, mom, dad):
print("【PChild】构造方法")
self.name = name
self.mom = mom
self.dad = dad

def cry(self):
print('【PChild】'+self.name + ":\'wow wow\'")

# 多重继承
class Kid(Student, Child):
def __init__(self, name, age, gender, student_number, mom, dad):
print("【PKid】构造方法--开始")
Student.__init__(self, name, age, gender, student_number)
Child.__init__(self, name, mom, dad)
print("【PKid】构造方法--结束")

def info(self):
print('【PKid】'+', '.join(['%s:%s' % item for item in self.__dict__.items()]))

# 创建一个Student对象
jerry = Student("Jerry", 17, 'male', '0021')
print(jerry.name)
jerry.say_hello()
# 创建一个Kid对象
kid = Kid("小明", 12, "男", "0023", "Tom", "Jerry")
kid.info()

​ Python执行结果

小结

​ Java与Python 3 在掉用构造方法时顺序是一致的,但是Java在构造方法内调用父类构造方法,语句super()必须放在方法体的第一句;而Python 3,对象是由 __new__() __init__()协作构造完成,实例通过__new__方法被创建,使用__init__方法进行初始化;所以在调用父类方法之前,可以对参数进行定制修改。Python 3 的多继承,在搜索从父类继承的方法/属性时,可以简单认为是深度优先、从左至右;但为了保持单次调用,实际在调用时是动态的;

多态

​ 实现多态的步骤:1.继承父类 2.重写父类方法 3.向上转型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**1.Teacher继承自People**/
public class Teacher extends People {

public Teacher() {
}

public Teacher(String name, int age, String gender) {
super(name, age, gender);
}
//2.重写sayHello方法
public void sayHello() {
System.out.println("【JTeacher】"+this.getName() + ":\" 同学们早上好!\"");
}
}
1
2
3
4
5
6
7
8
9
public class Test {
public static void main(String[] args) {
//3.向上转型
People teacher= new Teacher("王阳明",45,"男");
teacher.sayHello();
People student =new Student("小明", 17, "男", "0021");
student.sayHello();
}
}

java运行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Teacher(People):
"""继承自People"""
def __init__(self, name, age, gender):
print("【PTeacher】构造方法--开始")
super(Teacher, self).__init__(name, age, gender)
print("【PTeacher】构造方法--结束")

def say_hello(self):
print("【PTeacher】{} say:\"同学们好!\"".format(self.name))

people_1 = Student("小明", 12, "男", "0023")
people_1.say_hello()
people_2 = Teacher("王阳明", 45, "男")
people_2.say_hello()

Python运行结果:

小结

Python从语法层面并没有像Java那样提供对抽象类的支持,但是我们可以通过abc模块的ABCMeta元类和abstractmethodclass CLASSNAME(metaclass=ABCMeta):)包装器来达到抽象类的效果,如果一个类中存在抽象方法那么这个类就不能够实例化。

Java 设计模式之桥接模式

桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。

简单来说,可以通过桥接模式实现使用相同的抽象方法、不同的桥接实现类获得不同的结果。

阅读更多