ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

2021年Java进阶总结

2021年Java进阶总结

1、Spring之IoC/(DI)和AOP

依赖注入(Dependecy Injection)和控制反转(Inversion of Control)是同一个概念

依赖注入有三种注入方式:属性注入,构造器注入,工厂注入(静态工厂和实体工厂)

依赖注入的底层实现机制:反射机制

面向切面编程(AOP):分为前置通知、切面、后置通知、异常通知

前置通知:在方法执行前执行

切面:相当于要实现的功能

后置通知:在方法执行后执行

异常通知:在方法抛出异常后执行

面向切面编程的底层实现机制:动态代理

2、Spring、SpringMVC、Springboot的区别

Spring就是一个大的bean工厂,存储Bean的容器

常见的bean对象如:dataSource、事务、以及我们用的@Component 组件(spring的bean对象)@Controller 控制器@Service 服务@Repository 仓库注解后经过自动臊面

都会形成bean对象

SpringMVC:这个容器就相当于 一个请求发送过来后,经过SpringMVC容器获取,分析后进行对应spring容器里相应bean对象的转发,返回的值在经过SpringMVC容器响应给前端页面

Springboot:相对于Spring和SpringMVC主要的区别在于简化配置、内嵌Web服务器(Tomcat、Jetty等)、提供POM,简化Maven配置

3、Mybaites中$和#的区别

$:不能防止SQL注入

#:可以防止SQL注入

原因说明:$替换什么是什么,#是已占位符(?)的形式进行替换会默认加单引号(‘’)

4、WebService有哪些优势?

互操作性、跨平台性:应用程序可以使用Webservice以任何语言与另一个应用程序进行交互

更便宜的沟通成本:WebService确实使用SOAP over HTTP来允许任何人使用已经存在的用于WebService的Internet

5、ActiveMQ的作用总结(应用场景及优势)

业务场景说明:

队列的主要作用是消除高并发访问高峰,加快网站的响应速度。

在不使用消息队列的情况下,用户的请求数据直接写入数据库,在高并发的情况下,会对数据库造成巨大的压力,同时也使得系统响应延迟加剧。

在使用队列后,用户的请求发给队列后立即返回,

(例如: 当然不能直接给用户提示订单提交成功,京东上提示:“您提交了订单,请等待系统确认”),

再由消息队列的消费者进程从消息队列中获取数据,异步写入数据库。

由于消息队列的服务处理速度远快于数据库,因此用户的响应延迟可得到有效改善。

图解说明:

6、redis击穿、穿透、雪崩

缓存击穿:某一个数据缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,严重情况下会直接挂掉。

解决方法:1、添加互斥锁 2、设置热点数据永不过期(物理上的不过期、“逻辑上”的不过期(缓存到期动态构建缓存))

缓存穿透:当缓存与数据库中都不存在该数据时,由于当数据库查询不到数据就不会写入缓存,这个时候如果用户不断的恶意发起请求,就会导致这个不存在的数据每次请求都会查询DB,请求量大的情况下,就会导致DB压力过大,直接挂掉。

解决方法:1、当查询返回一个空数据时,直接将这个空数据存到缓存中,过期时间不宜设置过长,建议不超过5分钟 2、采用布隆过滤器

缓存雪崩:缓存中大批量的数据都到了过期时间,从而导致查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同,缓存击穿是指某一条数据到了过期时间,大量的并发请求都来查询这一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库

解决方法:1、设置热点数据永不过期 2、缓存数据的过期时间设置随机,可以在原有的过期时间上加上一个随机值,比如1-3min,防止同一时间大量缓存数据集体失效,导致数据库压力过大。 3、如果是分布式部署缓存数据库,可将热点数据分别存放到不同的缓存数据库中,避免某一点由于压力过大而down掉

7、redis哨兵模式

哨兵的作用:

监控(Monitoring):哨兵会不断地检查主节点和从节点是否运作正常

自动故障转移(Automatic failover):当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主节点的其中一个从节点升级为新的主节点,并让其他从节点改为复制新的主节点

配置提供者(Configurationprovider):客户端在初始化时,通过连接哨兵来获得当前 Redis 服务的主节点地址

通知(Notification):哨兵可以将故障转移的结果发送给客户端

它由两部分组成,哨兵节点和数据节点:

哨兵节点:哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的 Redis 节点,不存储数据

数据节点:主节点和从节点都是数据节点

哨兵系统的部署方法

这一部分将部署一个简单的哨兵系统,包含 1 个主节点、2 个从节点和 3 个哨兵节点

方便起见:所有这些节点都部署在一台机器上(局域网 IP:xxx.xxx.xx.xxx),使用端口号区分;节点的配置尽可能简化

8、sql优化

1、对查询进行优化,要尽量避免全表扫描,首先应考虑在where及order by 涉及的列上建立索引

2、应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描

3、应尽量避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描

4、应尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描

5、in 和 not in 也要慎用,否则会导致全表扫描,对于连续的数值,能用 between 就不要用 in 了,很多时候用 exists 代替 in

6、应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描

9、如何合理化新建索引

1、表的主键、外键必须有索引

2、数据量超过300的表应该有索引

3、经常与其他表进行连接的表,在连接字段上应该建立索引

4、经常出现在Where子句中的字段,特别是大表的字段,应该建立索引

5、索引应该建在选择性高的字段上

6、索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引

10、FastDFS(分布式文件系统)

它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题

11、elasticsearch的用途

概念:Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎

用途:Elasticsearch用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便

12、docker虚拟化容器技术

docker理顺了软件包的问题,有了docker运行一个镜像是非常容易的,不需要做各种环境的配置。

13、JenKins自动化部署工具

Jenkins是一个开源的、可扩展的持续集成、交付、部署(软件/代码的编译、打包、部署)的基于web界面的平台。允许持续集成和持续交付项目,无论用的是什么平台,可以处理任何类型的构建或持续集成。

14、Sonar代码质量监控工具

Sonar是一个用于代码质量管理的开源平台,用于管理源代码的质量,可以从七个维度检测代码质量

通过插件形式,可以支持包括java,C#,C/C++,PL/SQL,Cobol,JavaScrip,Groovy等等二十几种编程语言的代码质量管理与检测

15、Nginx正向代理和反向代理

正向代理是一个位于客户端和原始服务器之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。

反向代理实际运行方式是代理服务器接受网络上的连接请求。它将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给网络上请求连接的客户端,此时代理服务器对外就表现为一个服务器。

16、Modbus协议两种类型以及应用场景

两种类型:opc和tcp:OPC不需要转化 TCP协议是二进制需要自己转化

应用场景:软硬件设备

17、项目介绍两大块

业务介绍:系统中都做了哪些功能,这些功能一定是一个闭环操作,说清楚即可,强调一下一个功能是一个小闭环,多功能之间形成大闭环

技术实现:每个功能都是有哪些技术实现的?有点水平的就是高并发的解决,多系统之间通信等

18、设计模式有多少种?

创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式

结构型模式,共七种:适配器模式、装饰者模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

19、设计模式遵循的6大原则

1、单一职责原则 -----每个类应该实现单一的职责
2、里氏替换原则------继承复用,增加新的行为
3、依赖倒转原则------依赖抽象而不依赖具体
4、接口隔离原则------使用多个隔离的接口
5、迪米特法则--------只与直接的朋友通信,减少依赖
6、合成复用原则------使用合成/聚合的方式,而不是使用继承

20、冒泡排序和选择排序手写代码

冒泡排序

public class MyClass {
public static void main(String[] args) {
int arr[] = new int[]{1, 3, 5, 7, 9, 2, 4, 6, 8, 0};
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j + 1 < arr.length - i; j++) {
if (arr[j] < arr[j + 1]) {
int t = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = t;
}
}
}
for (int i = 0; i < arr.length; i++)
System.out.print(arr[i] + "\t");
System.out.println();
}
}

选择排序

int[] arr = {5, 1, 18, 2, 45, 31, -8};

int k = 0;

for (int i = 0; i < arr.length; i++) {

k = i;

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

if(arr[j] < arr[k]){

k = j;

}

}

int temp = arr[i];

arr[i] = arr[k];

arr[k] = temp;

}

21、单例模式两种手写代码

饿汉式单例

public class Singleton {

private Singleton(){}

private static Singleton instance = new Singleton();

public static Singleton getInstance(){

return instance;

}

}

懒汉式单例

public class Singleton {

private static Singleton instance = null;

private Singleton() {}

public static synchronized Singleton getInstance(){

if (instance == null) instance = new Singleton();

return instance;

}

}

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进