Java面试题(持续更新)

Java基础篇

修饰权限符

  • public: 可以被任何其他类访问。如果一个类是public的,那么你可以从任何其他类中访问它。
  • protected: 可以被同一包内的任何类访问。可以被不同包中的子类访问。但是,它不能被其他不同包中的非子类访问。
  • (default) package-private (没有修饰符)::可以被同一包内的任何类访问。不能被其他包中的类访问,无论它们是否是子类。  
  • private:只能被其所在的类访问。类的成员(如字段、方法、内部类等)可以声明为private,但最外层的类不能声明为private。 

equals()和hashCode的关系

HashSet,HastMap都不允许重复,在存放数据时会先调用HoahCode来判断和之前的数据是否重复,如果和其他对象的hashCode值一样就会再调用equals来判断是否是一个对应,equals如果也一样的话就断定是一个值。

可以使用 int Objects.hash(args...)函数来实现hashCode,参数一般填为自己的所有字段。

垃圾回收

System.gc(),建议vm进行垃圾回收的函数。

垃圾回收时,会从所有的GC Root作为是起始点,从这些点开始,垃圾回收器会尝试查找和访问堆上的对象。换句话说,从GC Root可以直接或间接地引用到的对象都被认为是"活动的",也就是还在使用中。而那些从GC Root无法访问到的对象则可能是垃圾,它们可能会在下一次垃圾回收时被清除。

以下是常见的GC Root:

  1. 虚拟机栈引用的对象:当前线程中的局部变量、参数、返回值等都属于这一类。

  2. 方法区中静态属性引用的对象:也就是所有的类级别的静态变量。

  3. 方法区中常量引用的对象:例如字符串常量池中的引用。

  4. 本地方法栈中JNI(即通常所说的Native方法)引用的对象。

  5. 活跃的线程本身。

  6. 所有被同步锁synchronized持有的对象。

硬引用、软引用、弱引用(虚引用)

各种引用的区别就是垃圾回收的时候,处理的方式不一样。

硬引用

普通创建的对象就是硬引用,除非引用变量在栈中被销毁,否则不会被回收。

软引用

一般作为缓存使用。

当系统内存充足时,持有软引用的对象不会被垃圾收集器回收。

当系统内存不足或即将耗尽时,持有软引用的对象会被垃圾收集器考虑回收,即使这个对象还有软引用指向它。

举例:

想要创建一个图像的缓存。你不希望一直持有这些图像,以防止占用太多内存,但当内存充足时,你也不希望它们被频繁地回收和重新加载。这时,软引用是一个很好的选择:

import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Map;public class ImageCache {private Map<String, SoftReference<Image>> cache = new HashMap<>();public Image getImage(String path) {SoftReference<Image> softRef = cache.get(path);if (softRef != null) {Image image = softRef.get();if (image != null) {return image; // 使用缓存中的图像}}// 缓存中没有图像或图像已被回收,重新加载它Image image = loadImageFromDisk(path);cache.put(path, new SoftReference<>(image));return image;}private Image loadImageFromDisk(String path) {// 从磁盘加载图像的代码// ...return new Image();}// Image类的定义,为简洁起见,此处省略实际实现private static class Image {}
}

多线程篇 

Java中有几种创建线程的方式

四种:继承Thread类,实现Runnable接口,

ThreadLocal

ThreadLocal只能放入一个对象和取出一个对象,但是很神奇的是,同一个线程中get出的对象是相同的。

static ThreadLocal<String> xin = new ThreadLocal<>(); 一般把这个变量作为静态变量写在工具类中,属于同一个线程的方法使用了,存入与取出的对象是一样的。

Spring篇

Bean的作用域

Spring中Bean默认作用域是单利的,spring中的一个类加上@Component时,这个类有一个属性为a,a默认为0,第一个通过@AutoWrite获取时设置a为1,第二次通过@AutoWrite获取这个类的示例时时a的值是1。

可以用过@Bean与@Scope("prototype")来设置作用域。

Spring 的常用作用域:

  1. Singleton: 默认。每个Spring容器只有一个实例。
  2. Prototype: 每次请求都新建实例。
  3. Request: 一个HTTP请求内共享同一个实例。
  4. Session: 一个HTTP Session内共享同一个实例。

MVC架构

MVC 是 Model-View-Controller 的缩写,它是一种设计模式。MVC 将应用程序逻辑分为三个互相关联的组件,以实现模块化和更容易的管理。以下是这三个组件的解释:

  1. Model(模型):这是应用程序的数据部分。它包含所有的业务逻辑、数据和规则。模型是独立于视图和控制器的,这意味着模型不知道用户界面如何显示数据。

  2. View(视图):这是用户看到和与之互动的部分。它负责展示模型的数据。当模型中的数据发生变化时,视图会相应地更新。

  3. Controller(控制器):控制器是模型和视图之间的接口。它接收用户的输入并决定如何处理。基于用户的行为,控制器可以请求模型进行更改或更新,或者更改视图的表示。

前后端分离的现在,后端已经没有View层了。

Server、Mapper,domain等层属于Model类,Controller层属于controller类。

Spring如何解决循环依赖

注意:如果A变量的构造函数需要B,B的构造函数需要A,这种是误解的。

能解决什么类型的循环依赖问题

如果两个Java类在它们的构造函数中相互依赖,那么这会导致问题,因为无法在初始化一个类的同时初始化另一个类。

但是,Spring框架确实提供了处理循环依赖的机制。以下是Spring如何解决这个问题的:

  1. 字段注入:如你所说,如果A类有一个B类型的字段,并且这个字段是通过Spring注入的,同时B类也有一个A类型的字段并且这个字段是通过Spring注入的,那么Spring可以解决这种依赖关系。这是因为Spring首先创建了A和B的实例,然后再为它们的字段注入依赖。

  2. Setter方法注入:与字段注入类似,使用setter方法注入也可以解决循环依赖。Spring首先创建对象实例,然后使用setter方法为对象注入依赖。

Spring解决循环依赖的原理

这里举例A依赖B。B依赖A:

初始化A时,会先创建A类原始的Bean(未填充属性的),然后把这个Bean放入二级缓存,并在三级缓存中创建A的工厂对象。

填充A的属性时,发现需要B,于是就创建B。

创建B时发现需要A,Spring会从一级缓存中查找A,找不到就去二级缓存中查找A,发现二级有A的早期实例,就会拿这个填充。

这时B创建完了,就用B填充A。

三级缓存的问题
三级缓存中的工厂是什么时候放进去的

三级缓存中的工厂对象是在bean实例化但还未完全初始化(如属性填充)时放进去的。

三级缓冲中的工厂有什么用

三级工厂就是为了返回未初始化完成的Bean而创建。三级工厂返回的Bean会放入二级缓存。

这么做是为了不影响二级中的Bean初始化,二级中的Bean初始化完成之后要直接放入一级缓存。

工厂返回的Bean与二级缓存中的Bean是一样的,同一个引用。

对象没有循环依赖的情况

当Spring容器开始初始化一个bean(例如A)时,它会首先调用A的构造方法来实例化它。

然后Spring会进行属性注入、执行初始化方法等其他初始化步骤。

一旦bean完全初始化,它会直接放入一级缓存,这时它已经是一个完全初始化的单例bean,可以被其他bean或应用代码引用。

常用注解

@Autowired与@Resource区别

这两个都是做Bean注入用的,@Resource并不是Spring的注解,他的包是javax.annotation.Resource需要导入,但是Spring支持改注解的注入。

共同点:都可以写在字段和setter方法上,两者如果都写在字段上。

@Autowired默认按照类型(byType)装配依赖对象

默认情况下他要求依赖的对象必须存在,如果允许为null,可以设置他的required属性为false。

如果我们想按名称(byName)来装配,可以结合@Qualifier注解一起使用,@Qualifier注解来指定名称。

@Resource默认按照名称(ByName)装配依赖对象,由j2ee提供

@Resource有两个重要的属性,name和type。

Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。

@Indexed

需要额外添加依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-context-indexer</artifactId>
</dependency>

这是@Indexed的依赖,添加这个依赖之后可以提高Springboot的启动速度。

添加这个依赖编译项目(使用Maven的install)后会自动把:@Component,@Indexed,@Controller,@Service,@Repository这些相关的额注解标注的类的路径自动包含在“target/META-INF/spring-components”文件中,启动时提高速度。

@Import

@Import注解的作用:让Spring容器从其他指定的配置类中加载被@Bean修饰过的方法。

public class Person {...
}public class Address {...
}@Configuration
public class MainConfig {@Beanpublic Person john() {return new Person("John");}
}@Configuration
public class AdditionalConfig {@Beanpublic Address newYorkAddress() {return new Address("New York");}
}@Configuration
@Import({MainConfig.class, AdditionalConfig.class})
public class CombinedConfig {@Autowiredprivate Person john;@Autowiredprivate Address newYorkAddress;@Beanpublic String johnsAddressInfo() {return john.getName() + " lives in " + newYorkAddress.getCity();}
}

上面代码中:

CombinedConfig类上的@Import注解使MainConfig和AdditionalConfig中所有用@Bean标注的方法的返回值被注册到Spring容器中。

当Spring启动并处理CombinedConfig时,它不仅会注册CombinedConfig中定义的beans,还会注册MainConfig和AdditionalConfig中定义的beans。这正是@Import注解的主要目的。

@Controller与RestController的区别

@RestController
public class HelloController {@GetMapping("/restController")public User test() {return new User();}
}@Controller
public class HelloController {@GetMapping("/controller")public User test() {return new User();}
}

@RestController:

它是一个组合注解,等同于 @Controller 和 @ResponseBody 的组合。
它意味着这个控制器的所有方法的返回值都将自动序列化为 JSON 或其他媒体类型,并作为 HTTP 响应的体返回。因此,当你访问 http://localhost/restController时,在浏览器中直接看到的是 xxx 对象的 JSON 表示。

问:@RequestMapping("/hello") public String Hello(){ return "hello"; } }:返回字符串时:RestController不是返回的json格式吗,为什么,为什么浏览器的网络相应中返回的是hello,而不是“hello”,为什么hello会直接输出到页面上,RestController什么时候返回json什么时候返回xml

答:

为什么返回的是 "hello" 而不是 “"hello"”?

当你返回一个简单的字符串时,Spring MVC 会直接将这个字符串作为响应体返回,而不会将它视为一个 JSON 字符串值。所以,返回的就是 hello 而不是 JSON 格式的 "hello"。

为什么 "hello" 会直接输出到页面上?

这是因为默认的 Content-Type 是 text/plain。所以浏览器会把它当作纯文本来处理,并直接显示。

@RestController 何时返回 JSON 和何时返回 XML?

@RestController 会基于请求的 Accept 头和项目的依赖来确定返回什么格式的数据。

如果请求头包含 Accept: application/json 并且你的项目中有合适的 JSON 库(如 Jackson),那么默认返回的是 JSON 格式。
如果请求头包含 Accept: application/xml 并且你的项目中有 XML 绑定库,那么会返回 XML 格式。
如果方法返回一个对象或集合,并且接受的请求头是 Accept: application/json,则 @RestController 通常会返回 JSON 格式的数据。如果没有特定的 Accept 头或者接受多种内容类型,那么通常默认返回的是 JSON,前提是你的项目中有相关的 JSON 库。

@Controller:

当你在方法上没有使用 @ResponseBody 注解时,@Controller 注解的方法默认返回的是一个视图(view)的名字(通常用于模板引擎,例如 Thymeleaf, JSP 等)。
http://localhost:86/controller 时方法返回的是一个 User 对象。但因为你没有指定视图名,也没有使用 @ResponseBody,Spring 将尝试查找一个与 User 对象名匹配的视图,这通常不是你想要的。
这里的视图,指的是JSP那种。

普通方法与REST风格方法的对比

REST风格:

在REST风格中,HTTP动词(方法)如 GET, POST, PUT, DELETE 通常有以下的含义和约定:

  1. GET:

    • 用于检索资源。
    • 它应该只是读操作,不会更改资源的状态或执行任何副作用。
    • 例如:GET /api/users/123 可以用来检索ID为123的用户的详细信息。
  2. POST:

    • 用于创建新资源。
    • 通常在创建新资源时使用,响应中经常会返回一个 Location 头,指示新创建资源的URI。
    • 例如:POST /api/users 可以用来创建一个新用户,请求体中包含用户的详细信息。
  3. PUT:

    • 用于更新现有资源或创建新资源(如果它不存在的话)。
    • 与POST不同,PUT是幂等的,这意味着多次执行同一个PUT请求应该总是产生相同的结果。
    • 例如:PUT /api/users/123 可以用来更新ID为123的用户的详细信息或创建一个新用户(如果它之前不存在)。
  4. DELETE:

    • 用于删除资源。
    • 例如:ELETE /api/users/123 会删除ID为123的用户。
  • URL 中可以使用路径变量来指定具体的资源实例,如 /api/users/{id}。
  • 数据通常以 JSON 或 XML 格式传输。
  • get类型请求用于查询,delete请求用来删除等。

REST风格使用多个参数:@GetMapping("/api/users/{userId}/orders/{orderId}");,对应的普通请求链接:“/api/userOrder?userId=123&orderId=456”。

普通风格:

GET /getUser?id=1:用来查询。

RESTful

REST 描述了一种理论上的架构风格和一组原则,而当一个 Web 服务实际遵循这些原则时,我们称其为 RESTful。

数据库篇

索引篇

什么是索引:

排好序可以快速查找的数据结构。

索引的优势与劣势:

优势:提高数据检索的效率,降低数据库的io成本,通过索引排序能够大大减少CPU的消耗(因为索引已经是排好序的)。

劣势:需要经常增删的表不建议使用索引,因为更新表的数据时,也会更新索引数据,会降低更新的速度。

索引的分类:

主键索引,单值索引,唯一索引,复合索引。

单值索引和唯一索引的区别就是,单值索引允许重复,单一索引不允许。

设计模式篇

观察者模式

对象间的一种一对多的关系,当一个对象的状态发生改变时,所有依赖它的对象都会通知并自动更新。

一般主线程中一个while(1)循环,不停的判断子线程的状态,状态变化时通知其它子线程,比如任务的撤销。

工厂模式

工厂根据传递过来的参数决定生产哪个对象,Spring中可以通过getBean方法获取对象的时候根据id或者name获取,就是简单的工厂模式。

适配器模式

将一个类的接口转换为客户希望的另一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。

装饰者模式(包装模式)

用来动态的为一个对象添加新的功能,装饰者模式是一种用于替代继承的技术,无需通过继承增加子类就能扩展对象的新功能,使用对象的关联关系替代继承关系,更加灵活,同时避免体系的快速膨胀。

代理模式

Spring AOP的实现就是代理模式。

策略模式

策略模式对应于解决某一个问题的一个算法族,允许用户从该算法族中任选一个算法解决莫一问题,同时可以方便的更换算法或者增加新的算法,并且由客户端决定使用哪个算法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/113363.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DELTA TAU ACC-24E2A 如何开始学习机器人技术

DELTA TAU ACC-24E2A 如何开始学习机器人技术 如果你想成为机器人革命的一部分(彻底改变我们的生活和工作方式&#xff0c;而不是真正推翻人类)&#xff0c;Simplilearn有你需要的东西。这人工智能和机器学习训练营与IBM和加州理工学院合作&#xff0c;涵盖了与机器人相关的重…

DLP是如何防止数据泄露的?

根据相关调查数据&#xff0c;未来五年全球企业数据泄露防护&#xff08;DLP&#xff09;市场预计将以21.03%的复合年增长率高速增长&#xff0c;到2026年市场规模将达到62.65亿美元。 PC访问地址&#xff1a;获取详细资料 https://isite.baidu.com/site/wjz012xr/2eae091d-1b…

【Javascript】构造函数的参数写法

目录 写法一&#xff08;固定参数&#xff09;&#xff1a; 写法二&#xff08;对象类型的参数&#xff09; 写法一&#xff08;固定参数&#xff09;&#xff1a; 如果参数与参数的值不对应 写法一 要求位置严格对应&#xff0c;明确知道对象的属性 写法二&#xff08;对象类…

Shader Graph25-UV移动旋转缩放(自定义函数)

我们将UV操作放入函数内&#xff0c;该函数的内容来自我之前的文章 Shader Graph24-摇晃树叶-CSDN博客 一、UE在Material中右键&#xff0c;新建Material Function。 增加输入 二、新建Material&#xff0c;命名为DemoUVRotationUseFunction Offset为偏移值&#xff0c;Rotat…

Vue基础与常用指令,Element基础

1.vue快速入门 vue概述 Vue是一套构建用户界面的渐进式前端框架 只关注视图层&#xff0c;并且非常容易学习&#xff0c;还可以很方便的与其它库或已有项目整合 通过尽可能简单的API来实现响应数据的绑定和组合的视图组件 特点 易用&#xff1a;在有HTMLCSSJavaScript的基…

Python 机器学习入门之K-Means聚类算法

系列文章目录 第一章 Python 机器学习入门之线性回归 K-Means聚类算法 系列文章目录前言一、K-Means简介1、定义2、例子3、K-Means与KNN 二、 K-Means实现1、步骤2、优化2.1 初始化优化之K-Means2.2 距离优化之elkan K-Means 三、优缺点1、优点2、缺点 前言 学完K近邻算法&a…

操作系统【OS】进程的通信

共享存储 各个进程对共享空间的访问应该是互斥的&#xff08;可以使用P、V操作&#xff09;低级通信 基于数据结构的共享速度慢、限制多高级通信 基于存储区的共享数据的形式、存放的位置由通信进程控制速度快 消息传递 进程间的数据交换以格式化的消息为单位 消息头&#…

qt配置halcon环境实现读入图像显示

首先&#xff0c;在Halcon里面写流程。 *读入图像 read_image (Image, cat) *获取图片大小 get_image_size (Image, Width, Height) *设置适应大小显示 dev_set_part (0, 0, Height-1, Width-1) *显示图像 dev_display (Image) 菜单栏的文件->导出程序备用。 QT新建工程&a…

JavaPTA练习题 7-5 输出所有的水仙花数

输出所有的水仙花数。所谓的水仙花数是指一个三位数&#xff0c;其各位数字的立方和等于该数本身。 举例&#xff1a;153就是一个水仙花数。 153 1*1*1 5*5*5 3*3*3 1 125 27 153 请注意&#xff1a;含有main方法的类&#xff08;class&#xff09;的名字必须命名为Main…

WebSocket 入门案例

目录 WebSocket入门案例WebSocket-server新增项目:添加依赖:yml:启动类&#xff1a; frontend-server前端项目&#xff1a;添加依赖&#xff1a;添加yml&#xff1a;启动类&#xff1a;前端引入JS:前端页面&#xff1a;后端代码&#xff1a;测试&#xff1a; WebSocket 入门案…

RabbitMQ官方案例学习记录

官方文档&#xff1a;RabbitMQ教程 — RabbitMQ (rabbitmq.com) 一、安装RabbitMQ服务 直接使用docker在服务器上安装 docker run -it -d --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3.12-management 安装完成后&#xff0c;访问15672端口&#xff0c;默认用户…

vmware 16pro安装 mac10.14.6,期间遇到的问题

1、分配硬盘内存尽量分大点&#xff0c;建议是40g&#xff0c;我分了80g&#xff0c;后面下载解压xcode发现还不够&#xff0c;又增加最后分了120g 2、安装过程&#xff0c;卡在选语言的地方&#xff0c;鼠标和键盘无法操作。需要在虚拟机设置中&#xff0c;勾选以下选项“显示…

记录--怎么写一个可以鼠标控制旋转的div?

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 说在前面 鼠标控制元素旋转在现在也是一个很常见的功能&#xff0c;让我们从实现div元素的旋转控制开始来了解元素旋转的具体原理和实现方法吧。 效果展示 体验地址 code.juejin.cn/pen/7290719… 实现…

C++设计模式_08_Factory Method工厂方法模式

文章目录 1. “对象创建模式”模式1.1 典型模式 2. 动机&#xff08;Motivation&#xff09;3. 代码演示Factory Method工厂方法模式3.1 常规方法3.2 面向接口的编程3.2.1 FileSplitter1.cpp3.2.2 MainForm1.cpp 3.3 Factory Method工厂方法3.3.1 ISplitterFactory.cpp3.3.2 Ma…

只需五步,在Linux安装chrome及chromedriver(CentOS)

一、安装Chrome 1&#xff09;先执行命令下载chrome&#xff1a; wget https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm2&#xff09;安装chrome yum localinstall google-chrome-stable_current_x86_64.rpm看到下图中的Complete出现则代表安装…

分布式锁之mysql 锁

文章目录 使用数据锁&#xff1a;悲观锁 或者 乐观锁悲观锁乐观锁mysql锁总结 使用数据锁&#xff1a;悲观锁 或者 乐观锁 一个sql&#xff1a;直接更新时判断&#xff0c;在更新中判断库存是否大于0 update table set surplus (surplus - buyQuantity) where id 1 and (surp…

Kotlin笔记(五):泛型基础,委托

1. 泛型 Java自1.5版本引入了泛型的概念, Kotlin自然也支持泛型,Kotlin的泛型跟Java的泛型有相同之处,也有一些特别之处. 1.1 泛型类和泛型方法 在一般的编程模式下&#xff0c;我们需要给任何一个变量指定一个具体的类型&#xff0c;而泛型允许我们在不指定具体类型的情况下进…

记录阿里云服务器(Centos7.9)部署Thingsboard(3.4.2)遇到的一些问题

记录编译Thingsboard遇到的一些问题 部署了一个thingsboard项目到阿里云服务器上&#xff0c;历时十一天&#xff0c;遇到了很多困难&#xff0c;国内关于Thingsboard的资料确实很少&#xff0c;所以想着写一篇博客记录一下&#xff0c;或许能够给以后编译遇到类似问题的人一些…

Python+playwright 实现Web UI自动化

实现Web UI自动化 技术&#xff1a;Pythonplaywright 目标&#xff1a;自动打开百度浏览器&#xff0c;并搜索“亚运会 金牌榜” 需安装&#xff1a;Playwright &#xff08;不用安装浏览器驱动&#xff09; # 使用浏览器&#xff0c;并可视化打开 browser playwright.ch…

tomcat、nginx实现四层转发+七层代理+动静分离实验

实验环境&#xff1a; nginx1——20.0.0.11——客户端 静态页面&#xff1a; nginx2——20.0.0.21——代理服务器1 nginx3——20.0.0.31——代理服务器2 动态页面&#xff1a; tomcat1——20.0.0.12——后端服务器1 tomcat2——20.0.0.22——后端服务器2 实验步骤&…