首页 > 编程语言 >java社招面试题(亲身经历8w字,持续更新中)

java社招面试题(亲身经历8w字,持续更新中)

时间:2024-09-12 15:53:15浏览次数:11  
标签:面试题 社招 java 对象 模式 token Java 序列化 ID

1.1pom文件的常见标签
  • <groupId>: 定义项目的组 ID,通常是组织的域名倒写,如 com.example

  • <artifactId>: 定义项目的工件 ID,是项目的唯一标识符

  • <version>: 定义项目的版本号,如 1.0.0

  • <packaging>: 指定项目的打包类型,如 jarwar 等,默认为 jar

  • <dependencyManagement>: 用于集中管理项目依赖的版本,常用于父 POM。

  • <plugins>: 包含构建插件的集合。

  • <distributionManagement>: 定义项目的分发管理,包括部署仓库和站点信息。

1.2deploy什么作用

部署把项目发到远程仓库

1.3父子pom如何继承
  • 父项目引用:子项目的POM文件中指定父项目的<parent>元素。
  • 依赖管理:在父项目的POM文件中使用<dependencyManagement>元素管理依赖版本,子项目引用时无需指定版本号。
  • 插件管理:在父项目的POM文件中使用<pluginManagement>元素管理插件版本,子项目继承这些插件配置。
  • 属性继承:父项目的POM文件中定义的属性可以在子项目中直接使用。
  • 通用配置:将通用的配置放在父项目的POM文件中,子项目自动继承这些配置。

 2.Idea无法下载springboot源码

1.cmd 进入项目的根目录

2.2、执行命令 mvn dependency:resolve -Dclassifier=sources

3.Int表示的最大数

2^31-1

int表示是4字节,32位,第一位代表正负号,所以是2^31-1

4.重写重载区别

重载:同一个类,方法名相同,参数列表不同

重写:子类父类,参数列表相同,返回值类型相同,访问权限要子类大于父类

篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

需要全套面试笔记的【点击此处即可】免费获取

5.I/O多路复用

一个或者多个线程来处理多个socket的技术,无需创建更多的线程,减小系统开销。

实现io多路复用的模型总共有三种,分别是select,poll,epoll

select:轮询遍历,轮询fd数组,随fd数量增多,性能会下降,On

poll:和select一样,但使用链表存fd,On

epoll:使用b+树存储fd,基于回调去获取连接,O1。缺点:只有linux系统支持

而我们Nginx,Redis的轮询也会优先采取epoll模型

6.new Integer(100)和Integer.valueOf(100)区别

一个是new对象,一个是从缓存中拿

-128~127

7.CPU彪增如何解决

先top命令 找到占用率最高的进程

ps -mp 2308 -o Thread,tid,time 找到占用率最高的线程 发现是2320 线程,再转换为10进制

jstack 2308 | grep 910

分析


 8.MVC各层

MVC是一种常用的软件架构模式,它将应用程序分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。各层技术如下:

1. 模型层(Model):用于管理应用程序中的数据和相关业务逻辑,通常使用数据库和数据访问技术实现。常用的技术包括JPA、Hibernate、MyBatis等。

2. 视图层(View):用于呈现应用程序的用户界面,通常使用HTML、CSS、JavaScript等技术实现。在Web应用中,常用的技术包括JSP、Thymeleaf、Freemarker等。

3. 控制器层(Controller):用于协调模型层和视图层之间的交互,处理用户的请求并相应地调用模型层的方法。常用的技术包括SpringMVC、Struts、Servlet等。

好处
  1. 易于维护和扩展:MVC 架构将应用程序按照职责分为三个部分,每个部分之间的耦合性较低,因此更加容易维护和扩展。比如,修改模型不会影响视图和控制器,修改控制器也不会影响模型和视图。

  2. 模块化设计:MVC 架构将应用程序按照职责分为三个部分,每个部分之间的耦合性较低,可以独立地开发和测试每个部分,从而实现模块化的设计。

  3. 视图和模型分离:MVC 架构将视图和模型分离,视图只负责显示数据,模型只负责处理数据。这种分离使得可以方便地修改视图或模型,而不会影响到另一个部分。

  4. 多人协作:使用MVC架构可以实现模块化的设计,每个人负责一个模块,这样不同的人负责不同的部分,在执行任务时可以提高效率,提高项目的开发效率。

9.JWT实现登录功能

分为社交登录和账号密码登录

用户输入账号密码后,后端进行验证,查询数据库进行匹配

有签名,防止参数被篡改

 如何续命

双token方案

登录成功以后,后端返回 access_token 和 refresh_token,客户端缓存此两种token;

使用 access_token 请求接口资源,成功则调用成功;如果token超时,客户端携带 refresh_token 调用token刷新接口获取新的 access_token;

后端接受刷新token的请求后,检查 refresh_token 是否过期。如果过期,拒绝刷新,客户端收到该状态后,跳转到登录页;如果未过期,生成新的 access_token 返回给客户端。

客户端携带新的 access_token 重新调用上面的资源接口。

客户端退出登录或修改密码后,注销旧的token,使 access_token 和 refresh_token 失效,同时清空客户端的 access_token 和 refresh_toke。

10.cookie,session,token区别

他们主要的作用就是登录验证

首先咱们http是无状态的,什么是无状态,就是服务器记不住东西,如果想让服务器有记忆,那么cookie就出现了

 篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

需要全套面试笔记的【点击此处即可】免费获取

1. Cookie

浏览器发给服务器请求,比如输入账号密码,服务器会set-cookie后返回给客户端,可以设置过期时间,但cookie(账号密码)保存在客户端不安全。

2. Session
session是存储在服务端的,是基于cookie的,浏览器第一次发请求时,比如输入账号密码,在服务端会创建一个jsessionid

{
    jsessionId:63sa754d4f//存在服务器的内存里
    username:123
    password:456
}

和域名绑定,只是针对某个域名,发请求才携带cookie,分布式项目需要解决子域的session共享问题, springsession解决

然后返回给客户端一个jsessionid,之后每次请求都会携带jsessionid,服务端就去做验证

3. Token

通常存储在客户端,可以是浏览器的本地存储,例如LocalStorage或SessionStorage,

Token通常存储在客户端,可以是浏览器的本地存储,例如LocalStorage或SessionStorage,也可以是在客户端内存中,每次请求都会携带token,服务端会根据相应的秘钥对其进行验证

11.登录如何做

使用jwt做

首先,前端把敏感信息通过公钥加密,然后再传到后端。后端返回一个jwt,留作下次前端访问时携带。这时会有一个问题,如果此时jwt被黑客截取,那么黑客不就可以永远登录了吗?

如果黑客成功截取了第一次从后端传递给前端的 JWT,那么他可以使用该 JWT 进行登录。这是因为 JWT 的核心就是利用签名机制来防止篡改和伪造,而在第一次生成 JWT 并传递给前端的过程中,JWT 的签名是根据服务器端的密钥生成的,这个密钥是黑客不知道的。但是,一旦黑客获取了这个 JWT,他就可以使用该 JWT 进行登录,因为 JWT 中包含了用户的身份信息以及有效期等信息,后端会根据这些信息来判断用户是否有访问权限。

为了避免黑客利用被截取的 JWT 进行登录,我们可以采取以下措施:

1.使用https做为网络协议进行传输

2.定期更换秘钥,如果秘钥变了,黑客再登录时,后端验签肯定不行

3.缩短jwt的时间

黑客的问题解决了,那么jwt续命的问题还没解决,可以使用双token方案

最后还有一个问题,总是被ddos攻击怎么办?

可以增加服务器带宽,也可以验证你是不是人,也可以弄一个黑白名单封ip。但没啥用,直接接入高防服务器,让他们去解决。

12.单点登录

单点登录就是,登录一位置的系统,其余多系统同时登陆的技术

单点登录(Single Sign-On,SSO)是一种身份认证和授权机制,允许用户使用一组凭证(如用户名和密码)登录到多个应用程序中。

  1. 使用cookie来做

  2. 用户访问系统1的受保护资源,系统1发现用户未登录,跳转至sso认证中心,并将自己的地址作为参数;

  3. sso认证中心发现用户未登录,将用户引导至登录页面;

  4. 用户输入用户名密码提交登录申请;sso认证中心校验用户信息,如果成功,就创建授权令牌,之后保存一个cookie, 留下一个登录痕迹;

  5. sso认证中心带着令牌跳转会最初的请求地址(系统1);

  6. 系统1拿到令牌,去sso认证中心校验令牌是否有效;

  7. sso认证中心校验令牌,返回有效,注册系统1;

  8. 系统1使用该令牌创建与用户的会话,并把令牌保存在会话里,返回受保护资源;

  9. 用户访问系统2的受保护资源;

  10. 系统2发现用户未登录,跳转至sso认证中心,并将自己的地址作为参数;

  11. sso认证中心发现用户已登录,跳转回系统2的地址,并附上令牌;

  12. 系统2拿到令牌,去sso认证中心校验令牌是否有效;

  13. sso认证中心校验令牌,返回有效,注册系统2;系统2使用该令牌创建与用户的局部会话,返回受保护资源。

比较麻烦,不安全,信息存在用户端

2.OAuth2.0单点登录

成本比较高,信息存在服务器端,比较安全

14.如何对接短信接口

1.引依赖

2.复制一手工具类

3.把秘钥放入请求头中

4.把电话和短信内容和密码放入map中

5.调用工具类的方法给第三方平台发请求,

13.社交登录

可以做微博,qq等第三方登录,扫码或者输入账号密码

 

14.调优经验

1.查询调优

少用连表查询,多用vo封装。因为连表查询是非常慢的,效率非常低。

在特别耗时等功能,比如发短信,发邮件。使用异步的方式

2.jvm调优

大部分jvm调优就是减少fullgc的次数,因为fullgc代表着整个堆的垃圾回收,而垃圾回收会伴随着stw,用户体验感不好。

如何降低fullgc,根据具体问题具体分析,可以设置年轻代和老年代比例,也可以设置伊甸园区和from to区的比例,也可以更换垃圾回收器。这些都是具体问题具体分析。

3.数据库调优

总共分7步

1.sql优化

减少对数据库的访问次数,小表驱动大表,行裁剪,列裁剪,避免使用HAVING子句, HAVING 只会在检索出所有记录之后才对结果集进行过滤,这个处理需要排序,总计等操作。如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销。unionall(组合两张字段相同的表,不去重)代替union,exists代替distinct,用exists代替in

2.索引优化

3.表结构优化

4.数据量实在太大就算走索引也很慢,就需要分库分表

分库(垂直拆分):一般不会这么做,会使事务问题变复杂

分表(水平拆分):按条件,时间,地区等分成多个表,但中间会加一个代理层mycat,shardingsphere

5.基本设置优化

连接数设置,慢查询设置

6.硬件优化

包括服务器硬件和网络带宽,这一部分是运维来做,我就不细说了

 篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

需要全套面试笔记的【点击此处即可】免费获取

4.架构的优化

比如把常用的数据放在缓存中,比如使用负载均衡和水平扩展可以高效的处理请求,用nginx做动静分离,把静态页面都放在nginx,使用nginx来分担服务器压力,使用keepalived做故障转移

15.接口幂等性问题

接口幂等性问题是指在一次或多次请求后,返回结果不变的问题。常见的情况包括网络超时、客户端重试、服务端异常等原因导致同一个请求被多次执行。如何处理接口幂等性问题,以下是一些建议:

1.前端的按钮只能点击一次

2.增加一个状态字段,比如正在支付的订单状态为进行中,如果用户重复支付,因为订单id相同,查数据库如果订单正在支付就返回订单正在支付中.

3.加唯一索引,在重复添加数据时会出现异常

4.token机制,后端生成一个全局唯一token,加入redis,每次调用接口就带着这个token,之后从redis中拿出令牌对比,两个令牌相同就删除token.但需要保证这三个操作的原子性问题如果服务端由于网络延迟导致接口重复调用,因为令牌每次都是一个,所以也不会有幂等性问题,比如说生成订单的时候就同时生成一个防重令牌token,放入redis中,提交订单就携带这个token,再去redis查,最后再对比.可以解决订单重复提交的问题

5.乐观锁,加一个版本号字段,update的时候去判断版本号

16.流的分类

17.String为什么是不可变类

这是因为String类具有不可变性,即一旦创建了一个String对象,它的值就不能被修改。如果String类可以被继承,那么子类可能会修改父类中的字符串值,从而破坏了String类的不可变性。

String类的不可变性有以下几个好处:线程安全:由于String对象的值不可变,因此多个线程可以同时访问同一个String对象,而不需要担心线程安全问题。

18.反射的原理

jvm通过类加载器把类加载到内存中,一旦加载进来就会产生一个Class对象,我们就可以通过newInstance的方法来动态的创建对象

19.动态代理的原理

动态代理的原理是通过反射机制,在运行时动态地生成代理类。代理类实现了与被代理对象相同的接口,并在代理类中维护了一个被代理对象的引用。当代理类的方法被调用时,它会将方法调用转发给被代理对象,并在调用前后执行一些额外的逻辑,如记录日志、统计执行时间等。

Java中提供了两种动态代理方式:基于接口的动态代理和基于类的动态代理。基于接口的动态代理是通过Java的反射机制在运行时创建一个实现了指定接口的代理类,而基于类的动态代理是通过继承一个指定类来创建代理类。

动态代理的优点在于它能够在运行时动态地为对象添加额外的功能,而不需要修改原始类的代码。这种方式可以提高代码的复用性和灵活性,同时也可以减少代码的重复。

20.Arrays.sort的原理

一种混合排序算法,是多个排序算法合一起的混合排序。比如在某某区间到某某区间用什么排序,在某某区间到某某区间又用什么排序。这个排序算法不仅仅是java常用的算法,别的语言也用这个算法,说明这个算法的强大。

21.面向对象和面向过程的区别

面向对象(Object-oriented programming,OOP)和面向过程(Procedure-oriented programming,POP)是两种不同的编程范式。

面向过程是一种以过程为中心的编程方式,以实现为核心,将系统分解成若干个可单独独立实现的过程(函数或方法)。程序的执行流程是从一个过程转移到另一个过程,同时一些数据通过参数进行传递。对于复杂的问题,面向过程可能会导致代码繁琐和难以扩展。

面向对象则是一种以对象为中心的编程方式,将系统看作一个由对象组成的集合,对象之间通过消息传递来协同工作。每个对象都有自己的状态和行为,状态是对象的属性,行为则是对象的方法。对象可以根据需要随时创建、销毁和发送消息。面向对象的思想更具有灵活性和维护性。

面向对象的优势主要体现在下面几个方面:

  1. 可维护性:OOP 使得代码编写更加清晰、简洁,便于维护和扩展。

  2. 可重用性:OOP 支持代码的复用,使得开发人员可以编写和测试一些通用的、可重用的类,从而提高开发效率。

  3. 可扩展性:OOP 具有高度的灵活性和扩展性,对象之间的关系虽然复杂,但是可以在不影响其他部分的情况下添加新功能、新对象和新类。

  4. 松耦合:OOP 可以将封装性和继承带来的低耦合性高度融合,对象只与其它必需通信的对象产生联系,系统更加灵活。

  5. 代码的真实性:面向对象的语言中,对象模型往往是很贴切于问题本身的,因此编写出来的代码更有代表性,更能反映出问题的真正面貌。

面向对象具有很多优点,尤其适用于需要复杂数据类型或涉及许多对象交互的程序设计。同时,它也并不意味着就是万能的,不同的需求和场景可能需要不同的编程范式。

22.面向对象的三大特征

  • 封装:使数据更加安全。可以使用private,public等关键字控制访问权限

  • 继承:继承是让一个类具有父类的功能的一种机制。减少代码的重复,使代码更加简洁,提高代码的重用性和可维护性。

  • 多态:是同一方法名可以作用在不同的对象上,产生了不同的结果。它分为编译时多态(重载)和运行时多态(重写)。

23.跨域

跨域产生必须要同时满足两种情况,必须得是ajax请求,请求的域不同(协议,ip,端口)

在服务端设置响应头,来允许跨域, 

做可以通过nginx进行代理,让前后端的域相同

24.接口防刷怎么做

1.限制访问频率:通过生成一个带有过期时间的 token,限制客户端请求接口的频率。客户端在每次访问接口的时候,需要携带上该 token,后端就可以根据 token 来验证请求是否合法。如果 token 过期或者不存在,就拒绝该次请求。

2.前端滑动验证码

3.黑名单:如果总是这个ip违反规则那么就将这个ip拉入黑名单

25.浮点数为什么丢失精度

在计算机内存中,数字都是以二进制形式存储的,而浮点数使使用科学计数法来表示一个数值,浮点数在计算机内部分三部分。正负号,阶码(指数),尾数

BigDecimal对象包含两部分:整数部分和小数部分。其中整数部分存储为一个BigInteger对象,也就是了一种类似数组的数据结构来存储整数部分,小数部分存储为一个int类型的数字,就是将小数扩大N倍,转成整数后再进行计算,同时结合指数,得出没有精度损失的结果。

26.分布式项目如何生成全局唯一id

SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高

  1. 初始化需要设置数据中心 ID 和机器 ID;
  2. 获取当前时间戳(毫秒级);
  3. 如果时间戳和上次相同,表示在同一毫秒内,此时自增序列号,但需要先和 "4095" 进行与运算,得到序列号的后 12 位,如果为 0 则等待下一毫秒再生产 ID;
  4. 如果时间戳不同,则序列号归零,等待在新的时间戳内生成 ID;
  5. 返回生成的全局唯一 ID。

     篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

    需要全套面试笔记的【点击此处即可】免费获取

27.向浏览器发送一个请求的具体过程

1:DNS解析,得到IP地址

浏览器得到是一个域名,需要把这个域名转化成IP地址才能找到服务器。DNS解析就是将域名转化为IP地址的过程。
解析的过程总的来说,是先在本地缓存里寻找域名对应的IP地址,没有找到就去域服务器递归寻找,找到后返回给浏览器并存到本地缓存。
2:浏览器根据IP地址,访问服务器,建立TCP连接
3:建立完TCP连接后,浏览器向服务器发送http请求
4:服务器返回http响应给浏览器
5:浏览器根据响应渲染页面呈现给用户
6:浏览器关闭TCP连接

28.Java序列化原理

Java 序列化机制是将一个 Java 对象转化为字节序列,便于在网络上传输或者保存到文件中。Java 序列化的原理大致分为以下几个步骤:

  1. 对象输出流(ObjectOutputStream)会将对象转化为字节序列。在将对象序列化为字节序列之前,需要先校验对象类是否可序列化。如果对象实现了 Serializable 接口,就可以被序列化。如果没有实现 Serializable 接口,就会抛出 NotSerializableException 异常。

  2. 对象输出流会遍历对象的属性和方法,将它们的名称和值序列化到字节数组中。

  3. 对象输出流采用的是流式写入,将序列化后的字节序列写入到文件或者网络中。可以使用文件输出流或者网络输出流实现这个操作。

  4. 反序列化时,需要使用对象输入流(ObjectInputStream)将字节序列反序列化为对象。对象输入流会读取字节序列,并根据字节序列重建对象。如果字节序列不符合对象的属性和方法结构,就会抛出 InvalidClassException 异常。

  5. 在反序列化对象时,需要注意序列号 ID, 通过 serialVersionUID 来校验当前对象的版本是否一致。如果版本不一致,可以通过自定义的 writeObject 和 readObject 方法进行序列化版本的控制,从而保证反序列化的对象与序列化时的对象是一致的。

总的来说,Java 序列化机制就是通过将 Java 对象的属性和方法转化为字节序列,再将字节序列写入文件或者网络中,从而实现数据的持久化和传输。

serialVersionUID的作用

Java 序列化就是将 Java 对象转化为可存储或传输的格式,这个格式可以是二进制流、XML、JSON 等。Java 序列化中的序列号 ID(SerialVersionUID)是一个 64 位的 hash 值,用于在对象序列化和反序列化时判断对象的版本一致性。

当我们序列化一个对象时,Java 会自动为这个对象分配一个序列号 ID。然后在将对象序列化的时候,将这个对象的类型和序列号 ID 一并写入序列化的文件中。这样在反序列化对象时,Java 就可以根据文件中的序列号 ID 获取这个对象的类型,然后校验当前对象的序列号 ID 是否与文件中的序列号 ID 一致。

如果当前对象的序列号 ID 与文件中的序列号 ID 不一致,Java 将抛出 InvalidClassException 异常。这是因为在反序列化时,Java 无法匹配到正确的类定义,导致反序列化失败。

因此,序列号 ID 主要用于保证序列化和反序列化时对象的版本一致性,防止出现对象类的不兼容问题。

如何将GBK编码转成UTF8
  1. 将 GBK 编码的字符串转换成字节数组
byte[] gbkBytes = gbkStr.getBytes("GBK");
  1. 将字节数组使用 UTF-8 编码转换成字符串。
String utf8Str = new String(gbkBytes, "UTF-8");

29.包装类的好处

  1. 可以在集合中存储基本类型的值。集合类只能存储对象,不能存储基本数据类型。将基本数据类型转换成对应的包装类型后,可以在集合类中存储基本类型的值。

  2. 提供了一些额外的方法。包装类可以调用一些基本类型所没有的方法。例如,Integer类提供的toHexString()方法可以将整数转换成16进制字符串。面向对象的理念中,应该是某些操作本该由区别明确的类负责,故应该为基本类型补充相关的方法。

  3. 允许 null 值。基本类型不能为null值,而包装类允许为null值。当需要使用到null值时,使用包装类更加方便。

  4. 使代码更具可读性和可维护性。使用包装类可以使代码更具可读性和可维护性。同时,也可以使代码更具可重用性,使得开发工作更加简单和高效。

综上所述,使用包装类相比于基本数据类型,具有更多的灵活性和可扩展性,同时也使得代码更加易读、易维护。然而,在计算或比较时,使用基本数据类型通常会更加高效。

30.数据库连接池用的什么,怎么配置的

druid数据源, 通过@ImportResource(locations={“classpath*:spring-db.xml”})引入数据库相关配置


  1. spring.datasource.druid.initial-size=5 初始化连接数

  2. spring.datasource.druid.min-idle=5 最小空闲连接数

  3. spring.datasource.druid.max-idle=10 最大空闲连接数

  4. spring.datasource.druid.max-active=20 连接池中允许的最大连接数

  5. spring.datasource.druid.max-wait=60000 获取连接的最大等待时间

  6. spring.datasource.druid.time-between-eviction-runs-millis=60000 检测线程的运行间隔时间 清理空闲连接

  7. spring.datasource.druid.min-evictable-idle-time-millis=300000 连接池中保持空闲状态的最短时间

  8. spring.datasource.druid.max-evictable-idle-time-millis=900000 连接池中保持空闲状态的最长时间

  9. spring.datasource.druid.validation-query=SELECT 1 通过执行指定的SQL 查询来验证连接是否可用。如果连接不可用Druid会将其移出连接池,并尝试创建新的连接来替换它。

  10. spring.datasource.druid.test-while-idle=true 连接处于空闲状态时进行连接有效性检查

  11. spring.datasource.druid.test-on-borrow=true 从连接池里拿出连接时进行有效性检查SELECT 1

  12. spring.datasource.druid.test-on-return=false 归还连接时进行有效性检查

  13. spring.datasource.druid.keep-alive=true 防止数据库服务器因长时间空闲关闭连接。

  14. spring.datasource.druid.filters=stat 收集连接池的统计信息,包括活跃连接数、空闲连接数、SQL 执行时间等

读取quartz-job.xml是用类加载器

先用ClassLoader.getSystemClassLoader().getResource("quartz-job.xml").getPath获取quartz-job的配置文件路径
然后通过SAXReader读取XML文件,不用注解导入是因为它不是bean对象

flie.properties文件是通过,继承PropertyPlaceholderConfigurer类,重写convertProperties方法,解析flie.properties文件至Global,保存系统配置

31.虚拟机和容器的区别

相同点

  • 都是通过虚拟化技术来实现资源的隔离和管理。
  • 都可以在同一台物理服务器上运行多个实例,从而提高硬件利用率。

容器的好处

启动速度快(通常几秒钟,容器可以动态分配资源,资源利用效率高,容器支持微服务架构,易于扩展和缩减

2.设计模式

1.设计模式的7大原则

  • 单一职责原则:一个类只有一个职责
  • 接口隔离:一个接口只有一类职责
  • 依赖倒转:高层模块不应该依赖低级模块,应该依赖他们的抽象或者实现(接口定义规范把细节留给他们的实现类)

        代码案例:


  1. public class DependencyInversion {

  2. public static void main(String[] args) {

  3. //客户端无需改变

  4. Person person = new Person();

  5. person.receive(new Email());

  6. person.receive(new WeiXin());

  7. }

  8. }

  9. //定义接口

  10. interface IReceiver {

  11. String getInfo();

  12. }

  13. class Email implements IReceiver {

  14. public String getInfo() {

  15. return "电子邮件信息: hello,world";

  16. }

  17. }

  18. //增加微信

  19. class WeiXin implements IReceiver {

  20. public String getInfo() {

  21. return "微信信息: hello,ok";

  22. }

  23. }

  24. //方式 2

  25. class Person {

  26. //这里我们是对接口的依赖,而不是直接依赖实现类。

  27. public void receive(IReceiver receiver) {

  28. System.out.println(receiver.getInfo());

  29. }

  30. }

  • 里氏替换:子类可以继承父类的扩展,但不要改变父类原有功能
  • 开闭原则:对扩展开放,对修改关闭
  • 迪米特法则:一个类对自已依赖的类知道越少越好
  • 合成复用原则:多用合成和聚合方式,少用继承
扩展:类与类之间的关系

依赖(一个类用到了其他类)

泛化(继承)

实现

聚合(set注入)

组合(构造注入)

2.设计模式分类

  1. 创建型模式
    创建型模式专注于对象的创建方式,包括单例模式、工厂方法模式、抽象工厂模式、建造者模式和原型模式。
  • 单例模式:保证系统中只有一个对象实例,提供全局访问点。
  • 工厂方法模式:定义一个用于创建对象的接口,交由子类决定实例化的类。
  • 抽象工厂模式:提供一个创建相关或依赖对象的接口,而无需指定它们具体的类。
  • 建造者模式:将一个复杂对象的构建与它的表示分离,使同样的构建过程可以创建不同的表示。
  • 原型模式:通过复制现有的实例来创建新的对象,而不是在代码中直接创建。
  1. 结构型模式
    结构型模式关注类和对象的组合,包括适配器模式、桥接模式、组合模式、装饰器模式、外观模式、享元模式和代理模式。
  • 适配器模式:将一个类的接口转换成客户希望的另一个接口,使得原本接口不兼容的类可以一起工作。
  • 桥接模式:将抽象部分和它的实现部分分离,使它们可以独立地变化。
  • 组合模式:将对象组合成树形结构,以表示“部分-整体”的层次结构,并可以通过一个对象实例来操作整个树形结构。
  • 装饰器模式:动态地给一个对象添加一些额外的职责,就增加功能来说,比生成子类更为灵活。
  • 外观模式:为子系统中的一组接口提供一个统一的入口,使得在复杂的系统中能够更容易地进行操作。
  • 享元模式:运用共享技术有效地支持大量细粒度的对象。
  • 代理模式:为一个对象提供一个代用品或占位符,以便控制对它的访问。
  1. 行为型模式
    行为型模式关注对象如何相互交互、解耦对象之间的职责分配,包括责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式和访问者模式。
  • 责任链模式:避免请求发送者和接收者之间的耦合关系,使处理请求的对象连成一条链,并沿着这条链传递该请求,直到有对象处理为止。
  • 命令模式:将请求封装成对象,从而使你可以用不同的请求对客户进行参数化,对请求排队和记录日志,以及支持可撤销的操作。
  • 解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。
  • 迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示方式。
  • 中介者模式:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互作用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
  • 备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,之后就可以将该对象恢复到原先保存的状态。
  • 观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。
  • 状态模式:允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。
  • 策略模式:定义一系列算法,把它们一个个封装起来,并且使它们可相互替换,本模式让算法的变化独立于使用它的客户。
  • 模板方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
  • 访问者模式:表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。

3.单例

双重检查


  1. class Singleton {

  2. private static volatile Singleton instance;

  3. private Singleton() {

  4. }

  5. private static Singleton getInstance() {

  6. if (instance == null) {

  7. synchronized (Singleton.class) {

  8. if (instance == null) {

  9. instance = new Singleton();

  10. }

  11. }

  12. }

  13. return instance;

  14. }

  15. }

 篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题

需要全套面试笔记的【点击此处即可】免费获取

标签:面试题,社招,java,对象,模式,token,Java,序列化,ID
From: https://blog.csdn.net/CXY123654654321/article/details/142175999

相关文章

  • JavaSE:2、基本数据类型
    1、整数类型在Java中,整数类型包括以下几个:byte字节型(8个bit,也就是1个字节)范围:-128~+127short短整形(16个bit,也就是2个字节)范围:-32768~+32767int整形(32个bit,也就是4个字节)最常用的类型:-2147483648~+2147483647long长整形(64个bit,也就是8个字节)范围:-9223372036854775808~......
  • 最强Java面试八股文总结,欢迎收藏!
    MySQL八股文 问:Mysql的存储引擎有理解过吗?我比较了解就是Innodb,myisam,Memory。 Innodb:现在的mysql默认存储引擎就是innodb,主要就是因为它是唯一一个支持事务的存储引擎,支持表级锁和行级锁,其索引的底层结构使用的是B+树,在数据,索引,表结构都存储到.idb中。 Myisam:其不支......
  • 2024年Java常见面试题整理
    1、java为什么要有包装类型?主要原因包括以下几点:处理基本数据类型的null值:基本数据类型(如int,double等)不能直接赋值为null,而包装类型(如Integer、Double)可以表示null值,这对于某些业务逻辑和数据处理来说非常有用。提供额外功能:包装类型提供了一些额外的方法和功能,这些......
  • Java突击面试八股文(15个技术栈,持续更新中)
    1.Java如何避免死锁注意加锁的顺序,保证每个线程按顺序进行加锁;加锁时限,可以设置一个超时时间;注意死锁检查,这是一种预防机制,可以确保发生死锁的第一时间进行处理。3、多线程(线程池)2线程有哪些状态(生命周期)新建、就绪、运行、阻塞、死亡3如何获取多线程的返回值?深坑!如果......
  • JavaScript开发技巧必备【一】
    1、使用Object.entries()和Object.fromEntries()//将对象转换为数组并转换回来,以便于操作constperson={name:'jack',age:20};constentries=Object.entries(person);//[['name','jack'],['age',20]]constnewPerson=Object.fromEn......
  • elasticsearch学习笔记整理(含下面总结的面试题)
    elasticsearch是一个全文检索的搜索引擎Elasticsearch是一个基于Lucene的搜索服务器ES可以做全文检索、模糊查询(搜索)、数据分析(提供分析语法,例如聚合)。es是不能使用root用户进行启动的,要新创建一个用户才行创建用户:useraddqianfeng设置密码:passwdqianfeng早期es的结构......
  • java+opencv4来获取图像中轮廓的最小外接矩形
     举例:获取以下图片中的火车的最小外接矩形完成钱确认opencv的环境配置完整。要想查找图片中的轮廓信息,首先要获取图片的二制图,因为二制图的查找效率更高,具体原因自行百度。为了提高转换二制图的效率可以现将图片转换为灰度图。示例代码如下://将彩色图像转换为灰度图像M......
  • JAVA——方法
    publicstatic返回值类型方法名(参数){        //方法体        return数据;}一、定义与调用publicclassdemo9_12{publicstaticvoidmain(String[]args){//调用myName();}//定义publicstaticvoidmyN......
  • 力扣238 移动零 Java版本 时间复杂度为O(0)
    文章目录题目描述代码题目描述给定一个数组nums,编写一个函数将所有0移动到数组的末尾,同时保持非零元素的相对顺序。请注意,必须在不复制数组的情况下原地对数组进行操作。示例1:输入:nums=[0,1,0,3,12]输出:[1,3,12,0,0]示例2:输入:nums=[0]输出......
  • Java学习路线:从零基础到高级开发者的完整指南
    初学者入门指南1.环境搭建安装JDK:下载并安装最新版本的JDK(JavaDevelopmentKit)。配置环境:设置JAVA_HOME环境变量,并将bin目录添加到PATH中。选择IDE:使用Eclipse、IntelliJIDEA或其他任何你喜欢的Java集成开发环境。2.Java基础知识HelloWorld:编写你的第一个Java......