Fork me on GitHub

抽象类和接口的区别

总结

关键字不一样 抽象类是abstract 接口是interface

子类使用 抽象类使用extends ,接口使用implements

修饰符不同

接口的方法默认是public abstract 属性默认是public static final

抽象类的方法默认是public abstract 属性是任意的

区别:定义接口的关键字是:interface而定义抽象类的关键字是:abstract。

接口中成员不能有私有,抽象类可以。

接口中定义的成员,是 public static final类型,抽象类没有。

接口中的不能有普通方法,抽象类中可以。

相同:

两个都不new

区别 抽象类 接口
关键字 abstract class interface
组成 属性、常量、构造、普通方法 全局常量、抽象方法
权限 可以使用各种权限 只能够是public访问权限
子类使用 使用extends继承抽象类 使用implements实现接口
关系 抽象类可以实现多个接口 接口不允许继承抽象类,但是一个接口可以继承多个父接口
使用 都需要定义有子类,子类一定要覆写所有抽象方法,并且依赖子类对象的向上造型实现抽象类或接口的对象实例化操作
限制 一个子类只能继承一个抽象类 一个子类可以实现多个接口
阅读更多...

SpringMVC的工作流程

mark

1、用户发送请求至前端控制器DispatcherServlet。

2、DispatcherServlet收到请求调用HandlerMapping处理器映射器。

3、处理器映射器找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。

4、DispatcherServlet调用HandlerAdapter处理器适配器。

5、HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。

6、Controller执行完成返回ModelAndView。

7、HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。

8、DispatcherServlet将ModelAndView传给ViewReslover视图解析器。

阅读更多...

Spring常见问题

说说Spring?

Spring的核心是控制反转、依赖注入,Aop(面向切面)相当于把每个bean与bean之间的关系交给第三方进行管理。

说SpringIOC,SpringAOP?

SpringIOC,其实就是依赖注入、控制反转。相当于把每个bean与bean之间的关系交给第三方容器管理。而这个容器就是spring SpringAOP面向切面的编程,或AOP,是一种编程技术,允许程序模块化横向切割关注点,或横切的责任划分,如日志和事务管理。SpringAop就是用Java的动态代理

Spring的底层实现机制是什么?

使用Dom4j(解析XML)+Java反射机制

Dom4j其实就是解析XML。使用反射机制实例化bean。

SpringAOP用到了什么代理?

JDK动态代理:对实现了接口的类生成代理

CGLib代理机制:对类生成代理

动态代理和静态代理区别?

静态代理:有程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。

动态代理:在程序运行时,运用反射机制动态创建而成。

Spring注入有那些方式?

Set注入

构造器注入

静态工厂的方法注入

实例工厂的方法注入

Spring有哪些注解?

@Autoeired(按类型注入)

@Service(标示为注入为服务层)

@Resource(按名称注入)

@Controller(标识控制器bean id)

@RequestMapping(表示映射URL路径)

简述Spring的优缺点?

Spring的优点??

1.降低了组件之间的耦合性,实现了软件各层之间的解耦

2.可以使用容器提供的众多服务,如事务管理,消息服务等

3.容器提供单例模式支持

4.容器提供了AOP技术,利用它很容易实现如权限拦截,运行期监控等功能

5.容器提供了众多的辅助类,能加快应用的开发

6.spring属于低侵入式设计。代码的污染极低

8.独立于各种应用服务器

9.spring的DI机制降低了业务对象替换的复杂性

10.Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可以自由选择spring的部分或全部

缺点:

使用到了大量反射机制。反射机制非常占内存,服务器启动时会创建bean

Mybatis 的常见面试题

原文链接 Mybatis的常见面试题

1、#{}和${}的区别是什么?

1
2
3
4
5
6
7
8
#{}是预编译处理,${}是字符串替换。

Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;

Mybatis在处理{}时,就是把{}替换成变量的值。

使用#{}可以有效的防止SQL注入,提高系统安全性。

2、当实体类中的属性名和表中的字段名不一样 ,怎么办 ?

第1种: 通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致

1
2
3
<select id=”selectorder” parametertype=int” resultetype=”me.gacl.domain.order”> 
select order_id id, order_no orderno ,order_price price form orders where order_id=#{id};
</select>

第2种: 通过来映射字段名和实体类属性名的一一对应的关系

1
2
3
4
5
6
7
8
9
10
 <select id="getOrder" parameterType="int" resultMap="orderresultmap">
select * from orders where order_id=#{id}
</select>
<resultMap type=”me.gacl.domain.order” id=”orderresultmap”>
<!–用id属性来映射主键字段–>
<id property=”id” column=”order_id”>
<!–用result属性来映射非主键字段,property为实体类属性名,column为数据表中的属性–>
<result property = “orderno” column =”order_no”/>
<result property=”price” column=”order_price” />
</reslutMap>
阅读更多...

有没有哪句句子是真正写到你的心里去了?

原文来自 有没有哪句句子是真正写到你的心里去了?

扩展链接

我们这一代人的困惑文章

我们这一代人的困惑视频

1.因为害怕自己并非明珠而不敢刻苦琢磨,又因为有几分相信自己是明珠,而不能与砂砾碌碌为伍。

遂逐渐远离世间,疏避人群,结果在内心不断地用愤懑和羞怒饲育着自己懦弱的自尊心。

世界上每个人都是驯兽师吧,而那匹猛兽,就是每人各自的性情。

如今想起来,我真的是空费了自己那一点仅有的才能,徒然在口头上卖弄着什么“人生一世一事不为则太长,欲为一事则太短”的警句。

可事实是,唯恐暴露才华不足的卑怯的畏惧、和厌恶和钻研刻苦的惰怠,就是我的全部了。

《山月记》中岛敦

2.这些年一直在提醒自己一件事情,千万不要感动自己,大部分人看似努力,不过是愚蠢导致的。

什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了。

如果这些东西也值得炫耀,那么富士康流水线上任何一个人都比你努力多了。

人难免天生有自怜情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。

于宙 《我们这一代人的困惑》

惭愧,这就是我啊。

Java中Arrays.sort()的几种用法

来自Java中Array.sort()的几种用法

Java的Arrays类中有一个sort()方法,该方法是Arrays类的静态方法,在需要对数组进行排序时,非常的好用。

但是sort()的参数有好几种,下面我就为大家一一介绍,这几种形式的用法。

1. Arrays.sort(int[] a)

这种形式是对一个数组的所有元素进行排序,并且是按从小到大的顺序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.util.Arrays;

/**
* 1、Arrays.sort(int[] a)
* 这种形式是对一个数组的所有元素进行排序,并且是按从小到大的顺序。
* @author GaoHangHang
* @date 2018/06/28 10:11
**/
public class Main {
public static void main(String[] args) {
int[] a = {9,8,7,2,3,4,1,0,6,5};
Arrays.sort(a);
for (int i = 0; i < a.length; i++) {
System.out.println(a[i] + " ");
}
}
}

运行结果如下:

0 1 2 3 4 5 6 7 8 9

阅读更多...

成神之路4 Java的垃圾回收机制

参考资料:

《深入理解Java虚拟机》

《Hotspot实战》

理解Java垃圾回收机制

一个面试官对GC问题的分析

理解Java垃圾回收机制

Jvm内存模型

图解Java 垃圾回收机制

0. 序

Java 垃圾回收机制要考虑的问题很复杂,本文将阐述其三个核心问题,包括:

  • What 哪些内存需要回收?

    判断对象是否可以被回收的两种经典算法:

    1. 引用计数法
    2. 可达性分析算法
  • When 什么时候回收?(堆的新生代、老年代、永久代的垃圾回收时机,MinorGC 和 FullGC)

  • How 如何回收?(三种经典垃圾回收算法(标记清除算法、复制算法、标记整理算法)及分代收集算法 和 七种垃圾收集器)

1. 首先回顾Java内存模型

运行时内存模型,分为线程私有和共享数据区两大类,其中线程私有的数据区包含程序计数器、虚拟机栈、本地方法栈,所有线程共享的数据区包含Java堆、方法区,在方法区内有一个常量池。

运行时数据区域

(1)线程私有区:

  • 程序计数器:记录正在执行的虚拟机字节码的地址;
  • 虚拟机栈:方法执行的内存区,每个方法执行时会在虚拟机栈中创建栈帧;
  • 本地方法栈:虚拟机的Native方法执行的内存区;

(2)线程共享区:

  • Java堆:对象分配内存的区域;
  • 方法区:存放类信息、常量、静态变量、编译器编译后的代码等数据;
    • 常量池:存放编译器生成的各种字面量和符号引用,是方法区的一部分。
阅读更多...

Java 5 新特性

1.自动装箱、拆箱

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* 自动装箱、拆箱
*
* @author GaoHangHang
* @date 2018/06/02 23:29
**/
public class AutoBoxing {

public static void main(String[] args) {

int a = new Integer(66);
Integer b = 18;

Boolean flag = true;
boolean isBug = Boolean.FALSE;

}

}

2.并发库

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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
* 并发库
*
* @author biezhi
* @date 2018/2/8
*/
public class Concurrent {

/*
重入锁
*/
public void lock() {
Lock lock = new ReentrantLock();
lock.lock();
try {
System.out.println("hello world");
} finally {
lock.unlock();
}
}

/*
线程池
*/
public void condition() throws InterruptedException {
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
// do something
condition.await(10, TimeUnit.SECONDS);
System.out.println("Get result.");
}


public void executorService() {
ExecutorService executorService = Executors.newFixedThreadPool(3);
executorService.submit(new Runnable() {
@Override
public void run() {
System.out.println("Task is running.");
}
});
}

/*
阻塞队列
*/
public void blockingDeque() {
Queue<Integer> blockingDeque = new ArrayBlockingQueue<>(20);
blockingDeque.add(1);
blockingDeque.add(2);
blockingDeque.add(3);

blockingDeque.peek();
}

public void concurrentHashMap() {
Map<String, Integer> concurrentHashMap = new ConcurrentHashMap<>();
concurrentHashMap.put("Hello", 1);
concurrentHashMap.put("World", 2);

System.out.println(concurrentHashMap.get("Hello"));
}

public void copyOnWriteList() {
List<String> copyOnWriteList = new CopyOnWriteArrayList<>();
copyOnWriteList.add("a");
copyOnWriteList.add("b");
copyOnWriteList.add("c");

System.out.println(copyOnWriteList.size());
}

public void semaphore() {
Semaphore semaphore = new Semaphore(3);
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + " is working");
Thread.sleep(1000);
semaphore.release();
System.out.println(Thread.currentThread().getName() + " is over");
} catch (InterruptedException e) {
}
}

}

3.枚举

1
2
3
4
5
6
7
8
9
10
11
/**
* 枚举
*
* @author GaoHangHang
* @date 2018/06/12 0:28
**/
public enum EnumDemo {

RED, GREEN, YELLOW

}

4.for each

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
import java.util.Arrays;
import java.util.List;

/**
* for each
*
* @author GaoHangHang
* @date 2018/06/12 0:30
**/
public class ForEach {

public static void main(String[] args) {

int[] arr = {1, 4, 5, 7};

for (int i : arr) {
System.out.println(i);
}

List<String> names = Arrays.asList("王爵nice", "Gay冰", "A*熊");
for (String name : names) {
System.out.println(name);
}
}

}

5.generic

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
import java.util.HashMap;
import java.util.Map;

/**
* 泛型
*
* 泛型规范数据结构,泛型的本质是参数化类型,所操作的数据被指定为一个参数
*
* @author GaoHangHang
* @date 2018/06/12 0:33
**/
public class Generic<T> {

public T getById() {
return null;
}

public static void main(String[] args) {

Map<String,Integer> map = new HashMap<>();

Generic<Long> generic = new Generic<>();

}
}

6.静态导入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import static java.lang.System.out;

/**
* 静态导入
*
* @author GaoHangHang
* @date 2018/06/12 0:44
**/
public class StaticImport {

public static void main(String[] args) {
out.println("Hi let learn java 8.");
}

}

7.变长参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.util.Arrays;
import java.util.List;

/**
* 变长参数
*
* @author GaoHangHang
* @date 2018/06/12 0:53
**/
public class VarArgs {

public static List<String> asList(String[] names){
return Arrays.asList(names);
}

public static void main(String[] args) {
List<String> hello = Arrays.asList("王爵nice", "Gay冰", "A*熊");

}

}

Java中遍历Map的几种方式

参考资料 Java中如何遍历Map对象的4种方法 - CSDN博客

自己的总结

  1. 在for-each循环中遍历entrySet
  2. 在for-each循环中遍历keySet或values
  3. 使用Iterator遍历
  4. 先获取keySet再根据key获取value

效率比较:

1和3效率类同

2比1效率快10%

4比1慢了20%~200% 不建议使用

方法一 在for-each循环中使用entries来遍历

这是最常见的并且在大多数情况下也是最可取的遍历方式。在键值都需要时使用。

1
2
3
4
5
6
7
Map<Integer, Integer> map = new HashMap<Integer, Integer>();  

for (Map.Entry<Integer, Integer> entry : map.entrySet()) {

System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());

}

注意:for-each循环在java 5中被引入所以该方法只能应用于java 5或更高的版本中。如果你遍历的是一个空的map对象,for-each循环将抛出NullPointerException,因此在遍历前你总是应该检查空引用。

阅读更多...
  • Copyrights © 2015-2023 高行行
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信