java基础面试题

本文详细介绍了Java面试中的关键知识点,涵盖类与对象的区别、接口、类的六种关系、Spring框架的应用和原理、内存结构、SQL优化、并发与线程、HashMap数据结构、单点登录实现、SpringMVC流程、线程同步方法、动态代理实现、JSP与Servlet的区别、SQL注入防护策略、异常处理、HTTP请求方法的区别、跨域处理、Spring的依赖注入方式、Spring MVC运行流程、MyBatis中#{ }与${ }的差异、数据库范式、多级分类、缓存问题、分布式理解、Spring Cloud组件、远程调用、负载均衡策略、Nacos与Eureka的对比、Feign调用优化、Gateway过滤器、消息队列原理与实践、Elasticsearch基础知识等,是Java开发者面试的全面指南。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 类和对象的区别

类是一个独立的程序单位,他应该有个类名,它的内部包含了属性和服务两个主要部分
对象其实就是构成系统的一个基本单位 ,一个对象由一组属性和一组服务组成的
说白了,类就像一台机器,而对象就是类身上的零件

2. 接口

接口只能具有抽象方法,一个类可以实现多个接口,当类实现了接口以后就必须
实现接口中的所有的抽象方法

3. JAVA中类的六种关系

1.继承关系 2.聚合关系 3.依赖关系 4.组合关系 5.实现关系 6.关联关系

4. 为什么要用spring

基于POJO的轻量级,通过依赖注入和面向接口实现松耦合
面向切面编程(aop 不修改源代码的情况下对系统动态统一添加功能的一种技术,扩展性)

5. 为什么要有控制反转

控制反转是将组件之间的依赖关系从程序内部提到外部来管理
就是把创建对象的控制权进行转移,以前都是由自己来把控,而现在是交给第三方进行管理
就比如说转移给了IOC(Spring)容器进行管理,你要什么对象它就给你什么对象

6. 堆,栈,Hash结构

栈是后进先出的,类似于计算机的Ctrl+z撤回一样的
队列是先进先出的,类似于自助冰淇淋机的蛋筒一样的
Hash是一个KV结构字符串,key不可重复,唯一的Key对应一个自己的value

7. sql优化

1.查询SQL尽量不要使用select * ,而是具体字段
2.避免在where中使用or来连接条件
3.查询尽量避免返回大量数据
4.优化like语句
6.索引不要太多,一般5个以内
等等

8. 什么是进程,什么是线程 串行并行

电脑中会运行很多程序,每个程序有一个独立的进程,而进程之间是相互独立存在的
线程是进程中最小的执行单位,并且一个进程至少有一个线程
串行:比如说电脑要下载多个文件,串行是先开始下载A再去下载B 它们在时间上市不可
能发生叠加的。
并行:下载多个文件,开启多条线程,多个文件同时进行下载,是同一时刻发生的,并行
在时间上是叠加的

9. 线程安全

加synchronized同步锁,加Lock释放锁
线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行
保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。

10. HashMap的数据结构

可以用指定Key找到指定的Value,是一个数组加链表的结构,
整体是一个数组
数组的每一个位置是一个链表
链表每个节点的Value即我们存储的Object

11. 单点登录实现

用户访问浏览器,但是你又想保护服务器中的资源,就可以限制浏览器的请求,响应
合法的请求,忽略非法的请求,浏览器每次请求服务器,服务器创建一个会话id,后面第
二次 第三次请求都会带上会话id,服务器就知道这个会话id是不是同一个用户了
登录状态:假设浏览器第一次请求需要输入账号密码。服务器拿着用户的密码去数据库对比
正确的话就是合法用户,会给这个会话标记已登录的状态

12. SpringMVC流程

用户发送请求至前端控制器
前端控制器收到请求去调用处理器映射器
处理器映射器找到具体的处理器,生成处理器对象及处理器拦截器 返回
前端控制器调用处理器适配器
处理器适配器调用具体的后端处理器
后端控制器返回模型和视图
处理器适配器将后端控制器执行结果返回给前段控制器
前端控制器将模型和视图传给视图解析器
视图解析器解析后返回具体的视图
前端控制器根据视图进行渲染视图
前端控制器返回用户

13. sleep() 和 wait() 有什么区别?

类的不同:sleep() 来自 Thread,wait() 来自 Object。
释放锁:sleep() 不释放锁;wait() 释放锁。
用法不同:sleep() 时间到会自动恢复;wait() 可以使用 notify()/notifyAll()直接唤醒。

14. 怎么实现动态代理?

JDK 原生动态代理和 cglib 动态代理。
JDK 原生动态代理是基于接口实现的,而 cglib 是基于继承当前类的子类实现的。

15. JSP 和 servlet 有什么区别?

JSP 是 servlet 技术的扩展,本质上就是 servlet 的简易方式。servlet 和 JSP 最主要的不同点在于,servlet 的应用逻辑是在 Java 文件中,并且完全从表示层中的 html 里分离开来,而 JSP 的情况是 Java 和 html 可以组合成一个扩展名为 JSP 的文件。JSP 侧重于视图,servlet 主要用于控制逻辑。

16. 如何避免 SQL 注入?

使用预处理 PreparedStatement。
使用正则表达式过滤掉字符中的特殊字符。

17. 常见的异常类有哪些?

NullPointerException 空指针异常
ClassNotFoundException 指定类不存在
NumberFormatException 字符串转换为数字异常
IndexOutOfBoundsException 数组下标越界异常
ClassCastException 数据类型转换异常
FileNotFoundException 文件未找到异常
NoSuchMethodException 方法不存在异常
IOException IO 异常
SocketException Socket 异常

18. get 和 post 请求有哪些区别?

get 请求会被浏览器主动缓存,而 post 不会。
get 传递参数有大小限制,而 post 没有。
post 参数传输更安全,get 的参数会明文限制在 url 上,post 不会。

19. 如何实现跨域?

实现跨域有以下几种方案:
服务器端运行跨域 设置 CORS 等于 *;
在单个接口使用注解 @CrossOrigin 运行跨域;
使用 jsonp 跨域;

20. spring 常用的注入方式有哪些?

setter 属性注入
构造方法注入
注解方式注入

21. 说一下 spring mvc 运行流程?

spring mvc 先将请求发送给 DispatcherServlet。
DispatcherServlet 查询一个或多个 HandlerMapping,找到处理请求的 Controller。
DispatcherServlet 再把请求提交到对应的 Controller。
Controller 进行业务逻辑处理后,会返回一个ModelAndView。
Dispathcher 查询一个或多个 ViewResolver 视图解析器,找到 ModelAndView 对象指定的视图对象。
视图对象负责渲染返回给客户端。

22. MyBatis 中 #{}和 ${}的区别是什么?

#{}是预编译处理,${}是字符替换。
在使用 #{}时,MyBatis 会将 SQL 中的 #{}替换成“?”,配合 PreparedStatement 的 set 方法赋值,这样可以有效的防止 SQL 注入,保证程序的运行安全。

23. 数据库的三范式是什么?

第一范式:强调的是列的原子性,即数据库表的每一列都是不可分割的原子数据项。
第二范式:要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性。
第三范式:任何非主属性不依赖于其它非主属性。

24. 三级分类菜单

先准备好数据表,再查出所有分类以及子分类,以树形结构组装起来
再进行判断,如果里面的元素 == 0,那就表示是一个一级id,并把它们收集成一个List集合

25. 缓存穿透,击穿,雪崩

缓存穿透就是查询一个一定不存在的数据,因为出于容错考虑,如果从存储层查不到
就不写入缓存,会导致这个不存在的数据一直请求到存储层,如果流量太大 DB就会挂掉

缓存击穿就是设置了一些key,这些key如果正好过期的时候发来了超高并发的请求
因为key过期了,所以要从DB中去加载到缓存中,这个时候的超高并发的请求就可能把
后端的DB压垮

缓存雪崩就是指我们设置了同一个过期时间,导致缓存同一时间同时失效,请求全部
转发到DB,DB瞬间压力过重就雪崩

26. 分布式理解

因为我主要用的是springcloud 它的注册与服务用的是Eureka 它的各个节点之间都是
平等的,不存在主从的关系,只要有一个节点还在,就能保证服务正常调用,即使节点全部
挂掉,服务与服务之间也可以通过缓存来调用消息,这就保证了微服务之间的调用足够健壮

27. spring cloud的主键有哪些

注册中心,可以去拉取或注册服务信息
配置中心,拉取配置信息,可以做到热更新
服务网关,用户要访问我们的服务,对用户身份的一个校验,可以路由到我们的某个服务中

28. 远程调用(根据订单查id)

先在启动类中new一个RestTemplate对象发送http请求(使用getForObject方法)
,再提供你的url地址(因为服务方注册到了注册中心中,直接写服务名),带上返回值类型
在RestTemplate上加上@LoadBalanced注解实现负载均衡轮询远程调用

29. 负载均衡

用户发起请求(比如http://uerservice/user/1)其中userservice是服务名,
请求发出后会被负载均衡拦截器拦截(LoadBalancerInterceptor),根据服务名去
eureka中获取到对应的服务,eureka返回服务,负载均衡拦截器会根据IRule中的规则去服务
中挑选一个服务出来,最后返回给拦截器,拦截器会拿到选择好的服务去替换服务名称拿到真实
的url地址

1. 负载均衡规则

一种是通过IRule来new你想要的的规则(这种方式是全局的,也就是说你不管调用哪个服务都是
使用这个规则),一种是通过yml来指定服务名来定规则(这种的话就只是针对你指定的服务定的规则)

2. 负载均衡加载方式

Ribbon默认是使用懒加载,懒加载就是你服务启动的时候才会去创建Ribbon拦截器
,第一次请求数据较慢,所以可以配置饥饿加载方式(需要配置服务名,或者多个服务名),服务启动的时候
直接获取到服务的信息,第一次访问较快

3.负载均衡权重

权重策略是帮助一些性能比较差的服务器请求压力小一点,可以在nacos里面配置(值是0-1之间)
可以实现服务器的一些升级操作(权重0的话是完全不会被访问的)

30. nacos和eureka的共同点

都支持服务注册和服务拉取
都支持服务提供者心跳做健康监测

31. nacos和eurkea的区别

1)nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例则不会被剔除
2)临时实例心跳不正常会被剔除,非临时实例则不会被剔除
3)nacos支出服务列表编程的消息推送模式,服务列表更新更及时
4)nacos集群默认采用AP方式,当集群中临时实例时,采用CP模式,Eurkea采用AP模式
功能差异总结: Eureka不提供配置中心(需要配合Config实现配置中心),不支持动态刷新(需要配合MQ实现配置动态刷新),不支持分组,不提供权重设置功能(无法调整承载流量压力),没有管理界面。

32. nacos的热更新

1)通过@value注解注入,结合@RefreshScope来刷新配置
2)通过@ConfigurationProperties注入,自动刷新(在哪里调用方法就在哪里加)

33. nacos的统一配置管理

项目启动 --> 读取本地配置文件(application.yml)–> 创建spring容器 --> 加载bean

首先nacos是这样读取文件的过程,因为我们要实现热更新,所以我们就要在nacos来配置

项目启动 --> 读取nacos配置文件 --> 读取本地配置文件(application.yml)–> 创建spring容器 --> 加载bean

会变成这样 因为我们需要提前知道nacos的地址,我们可以创建一个bootstrap.yml文件(因为这个文件比application.yml
的优先级更高)所以我们可以将nacos的地址、名称、命名空间信息填写在bootstrap.yml文件里

34. 远程Feign调用

  1. 首先引入依赖

    org.springframework.cloud
    spring-cloud-starter-openfeign
  2. 然后在启动类添加@EnableFeignClients注解
  3. 编写FeignClient接口
  4. 使用FrignClient中定义的方法代替RestTemplate

35. Feign性能优化

把底层实现修改为HttpClient
1)首先添加依赖

io.github.openfient
feign-httpclient

2)再配置yml文件
feign:
httpclient:
enabled: true #支持HttpClient的开关
max-connections: 200 #最大连接数
max-conntions-per-route: 50 #单个路径的最大连接数

36. Feign的最佳实践

方式一(继承):给消费者的FeignClient和提供者的controller定义统一的父接口作为标准
方式二(抽取):将FeignClient抽取为独立模块,并且把接口有关的POJO、默认的Feign配置都放到这个模块中,提供给所有消费者使用

实现(方式二):首先创建一个公共的feign调用服务,把需要调用的POJO、方法等统一放在公共的feign调用服务中,如果其他服务需要调用 则只需要引入公共feign调用服务即可
因为最后可能会找不到bean(因为不在同一个服务下),可以在启动类中指定具体的FeignClient的字节码@EnableFeignClient(clients = UserClien.class)

37. 统一网关gateway

网关路由可以配置的内容包括:
1)路由id:路由唯一标示
2)uri:路由目的地,支持lb和http两种
3)predicates:路由断言,判断请求是否符合要求,符合则转发到路由目的地
4)filters:路由过滤器,处理请求或响应

38. gateway过滤器

过滤器的作用是对路由的请求响应做加工处理,比如添加请求头,配置在路由下的过滤器只对当前路由的请求生效defaultFilters可以对所有路由都生效的过滤器

39. gateway全局过滤器

全局过滤器的作用是对所有路由都生效的过滤器,并且可以自定义处理逻辑实现全局过滤器的步骤
1)实现GlobaFilter接口
2)添加@Order注解或者实现Ordered接口来实现过滤器先后执行顺序
3)编写处理逻辑

40. 过滤器的执行顺序

1)order值越小,优先级越高
2)当order值一样时,顺序是defaultFilter最先,然后是局部的路由过滤器,最后是全局过滤器

41. 认识MQ 同步异步

1)同步调用的优点
时效性较强,可以立即得到结果
2)同步调用的问题
耦合度高
性能和吞吐能力下降
有额外的资源消耗
有级联失败问题

1)异步通信的优点:
耦合度低
吞吐量提升
故障隔离
流量削峰
2)异步通信的缺点
依赖于Broker的可靠性、安全性、吞吐能力
架构复杂了、业务没有明显的流程线、你好追踪管理

42. MQ基本消息队列的消息发送流程

1)建立connection
2)创建channel
3)利用channel声明队列
4)利用channel向队列发送消息

MQ基本消息队列的消息接收流程:

1)建立connection
2)创建channel
3)利用channel声明队列
4)定义connsumer的消费行为bandleDelivery()
5)利用channel将消费与队列绑定

43. springAMQP接收消息

引入AMQP依赖,编写yml文件 在类上添加@Component,在方法上添加@RabbitListener直接接收消息即可

44. 描述下Direct(可以指定发送某个队列)交换机与Fanou(广播群发)交换机的差异?

Fanout交换机将消息路由给每一个与之绑定的队列
Direct交换机根据RoutingKey判断路由给哪个队列
如果多个队列具有相同的RoutingKey,则与Fanout功能类似

45. 描述下Direct交换机与Topic交换机的差异?

两者非常相似,只是Topic可以使用通配符#,*代表0个或多个

46. SpringAMQP中消息的序列化和反序列化是怎么实现的?

利用MessageConverter实现的,默认是JDK的序列化
注意发送方与接收方必须使用相同的MessageConverter(不能一个JDK一个json)

47. 初识elasticsearch

1 什么是elasticsearch?
一个开源的分布式搜索引擎,可以用来实现搜索、日志统计、分析、系统监控等功能

2 什么是elastic stack(ELK)?
是以elasticsearch为核心的技术栈,包括beats、Longstash、Kibana、elasticsearch

3 什么是Lucene?
是Apache的开源搜索引擎类库,提供了搜索引擎的核心API,elasticsearch就是基于Lucene的二次开发
因为Lucene只限于Java语言开发,学习起来很复杂,还是固定死的

4 什么是正向索引?
基于文档id创建索引。查询词条时必须先找到文档,而后判断是否包含词条

5 什么是倒排索引?
对文档内容分词。对词条创建索引,并记录所在文档的信息。查询先根据词条查询到文档id,而后获取到文档

6 分词器的作用是什么?
可以分词,首先可以把常用的搜索词语录入到分词器中,还可以省略不用或者敏感的词语
创建倒排索引时对文档分词,用户搜索时 对输入的内容分词

7 IK分词器有几种模式?
ik_smart: 智能切分,粗粒度(就是说比如4个字能分成词语的话就不会考虑3个字能不能分)
ik_max_word: 最细切分,细粒度(比如3个字能分成词语,它会考虑2个字能不能分成词语,就会导致一个词语多处显示,搜索力度加大 但是会导致内存消耗加大)

8 IK分词器如何扩展词条?如何停用词条?
利用config目录的IKAnalyzer.cfg.xml文件添加拓展词典和停用词典(作用看43.6)
在词典中添加扩展词条或者停用词条

9 mapping(映射,对索引库中文档的约束,类似于数据库中的设置主键不能为空等)常见属性有哪些?
type:数据类型
index:是否索引(默认是true)
analyzer:分词器(结合test使用)
properties:子字段

10 type常见的有哪些?
字符串:test(可分词的文本),keyword(精确值,例如:品牌、国家、ip地址 不可分割的)
数字:long、integer、short、byte、double、float
布尔:boolean
日期:date
对象:object

11 索引库操作有哪些?
创建索引库:PUT/索引库名
查询索引库:GET/索引库名
删除索引库:DELETE/索引库名
添加字段:PUT/索引库名/_mapping

12 文档操作
创建文档: POST/索引库名/_doc/文档id {json文档}
查询文档:GET /索引库名 /_doc/文档id
删除文档: DELETE/索引库名/_doc/文档id

修改文档:
全量修改: PUT/索引库名/_doc/文档id {json文档}
增量修改:POST/索引库名/_update/文档id {“doc”:{字段}}

13 RestClient操作索引库
初始化JavaRestClient
1)引入es的ResHighLevelClient依赖

org.elasticsearch.client
elasticsearch-rest-high-level-client
7.9.3

2)因为SpringBoot默认的ES版本是7.6.2,所以我们需要覆盖默认的ES版本

<java.version>1.8</java.version>
<elasticsearch.version>7.9.3</elasticsearch.version>

3)初始化ResHighLevelClient

public class HotelIndexTest {
    private RestHighLevelClient client;

    @BeforeEach
    void setUp() {
        this.client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://192.168.64.181")
        ));
    }

    @AfterEach
    void tearDown() throws IOException {
        this.client.close();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值