JavaEE 面试常见问题

一、常见的 ORM 框架有哪些?

1.Mybatis

Mybatis 是一种典型的半自动的 ORM 框架,所谓的半自动,是因为还需要手动的写 SQL 语句,再由框架根据 SQL 及 传入数据来组装为要执行的 SQL 。其优点为:
1. 因为由程序员自己写 SQL ,相对来说学习门槛更低,更容易入门。
2. 更方便做 SQL 的性能优化及维护。
3. 对关系型数据库的模型要求不高,这样在做数据库模型调整时,影响不会太大。适合软件需求变更比较频繁的系统,因此国内系统大部分都是使用如 Mybatis 这样的半自动 ORM 框架。
其缺陷为:
不能跨数据库,因为写的 SQL 可能存在某数据库特有的语法或关键词

2.Hibernate

Hibernate 是一种典型的全自动 ORM 框架,所谓的全自动,是 SQL 语句都不用在编写,基于框架的 API,可以将对象自动的组装为要执行的 SQL 语句。其优点为:
1. 全自动 ORM 框架,自动的组装为 SQL 语句。
2. 可以跨数据库,框架提供了多套主流数据库的 SQL 生成规则。
其缺点为:
学习门槛更高,要学习框架 API SQL 之间的转换关系
对数据库模型依赖非常大,在软件需求变更频繁的系统中,会导致非常难以调整及维护。可能数据库中随便改一个表或字段的定义,Java 代码中要修改几十处。
很难定位问题,也很难进行性能优化:需要精通框架,对数据库模型设计也非常熟悉。

二、Bean容器/Ioc容器的理解

Spring 容器主要是对 IoC 设计模式的实现,主要是使用容器来统一管理 Bean 对象,及管理对象之间的依赖关系。
创建容器的 API 主要是 BeanFactory ApplicationContext 两种:
1. BeanFactory 是最底层的容器接口,只提供了最基础的容器功能: Bean 的实例化和依赖注入,并且使用懒加载的方式,这意味着 beans 只有在我们通过 getBean() 方法直接调用它们时才进行实例化。
2. ApplicationContext (应用上下文)是 BeanFactory 的子接口,与 BeanFactory 懒加载的方式不同,它是预加载,所以,每一个 bean 都在 ApplicationContext 启动之后实例化。
3. 除了基础功能,还添加了很多增强:
  • 整合了Bean的生命周期管理
  • i18n国际化功能(MessageSource
  • 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的 web
  • 事件发布响应机制(ApplicationEventPublisher
  • AOP

三、IoC/DI的理解

概念

IoC (Inversion of Control) 即控制反转,是面向对象编程中的一种设计原则。主要是通过第三方 IoC 容器,对Bean 对象进行统一管理,及组织对象之间的依赖关系。获得依赖对象的过程,由原本程序自己控制,变为了IoC 容器来主动注入,控制权发生了反转,所以叫做 IoC ,控制反转。
IoC 又叫做 DI :由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),相对 IoC 而言,依赖注入实际上给出了实现 IoC 的方法:注入。所谓依赖注入,就是由 IoC 容器在运行期间,动态地将某种依赖关系注入到对象之中。
依赖注入 (DI) 和控制反转 (IoC) 是从不同的角度的描述的同一件事情,就是指通过引入 IoC 容器,利用依赖关系注入的方式,实现对象之间的解耦。

实现方式

DI IoC 的实现方式之一。而 DI 的实现方式主要有两种:构造方法注入和属性 Setter 注入。

实现原理

主要依赖反射及 ASM 字节码框架实现(字节码框架操作字节码更为高效,功能更强大)。

四、Spring中的单例bean的线程安全问题

大部分时候我们并没有在系统中使用多线程,所以很少有人会关注这个问题。单例 bean 存在线程问题,主要是因为当多个线程操作同一个对象的时候,对这个对象的非静态成员变量的写操作会存在线程安全问题。
有两种常见的解决方案:
1. bean 对象中尽量避免定义可变的成员变量(不太现实)。
2. 在类中定义一个 ThreadLocal 成员变量,将需要的可变成员变量保存在 ThreadLocal 中(推荐的一种方式)。

五、Spring中的bean的作用域有哪些?

1.singleton :唯一 bean 实例, Spring 中的 bean 默认都是单例的。
2.prototype :每次请求都会创建一个新的 bean 实例。
3.request :每一次 HTTP 请求都会产生一个新的 bean ,该 bean 仅在当前 HTTP request 内有效。
4.session :每一次 HTTP 请求都会产生一个新的 bean ,该 bean 仅在当前 HTTP session 内有效。
5.application :在一个应用的 Servlet 上下文生命周期中,产生一个新的 bean
6.websocket :在一个 WebSocket 生命周期中,产生一个新的 Bean

六、FactoryBeanBeanFactory

BeanFactory Spring 容器的顶级接口,所有 Bean 对象都是通过 BeanFactory 也就是 Bean 容器来进行管理
FactoryBean是实例化一个 Bean 对象的工厂类,实现了 FactoryBean<T> 接口的 Bean ,根据该 Bean 的 ID从 BeanFactory 中获取的实际上是 FactoryBean getObject() 方法返回的对象,而不是
FactoryBean 本身,如果要获取 FactoryBean 对象,请在 id 前面加一个 & 符号来获取。

七、Bean的生命周期

1. 实例化 Bean :通过反射调用构造方法实例化对象。
2. 依赖注入:装配 Bean 的属性
3. 实现了 Aware 接口的 Bean ,执行接口方法:如顺序执行 BeanNameAware BeanFactoryAware 、 ApplicationContextAware的接口方法。
4. Bean 对象初始化前,循环调用实现了 BeanPostProcessor 接口的预初始化方法 (postProcessBeforeInitialization
5. 执行 Bean 对象初始化方法
6. Bean 对象初始化后,循环调用实现了 BeanPostProcessor 接口的后初始化方法
postProcessAfterInitialization
7. 容器关闭时,执行 Bean 对象的销毁方法

八、Spring三级缓存的理解

这个问题或者换个问法: Spring 是如何解决循环依赖的?答案即是 Spring 的三级缓存

什么是循环依赖

简单说,就是 A 对象依赖 B 对象, B 对象又依赖 A 对象,类似的代码如下:
@Component
public class A{
@Autowired
private B b;
}
@Component
public class B{
@Autowired
private A a;
}
其他还有很多种方式,如 A 依赖 B B 依赖 C C 依赖 A ,或是 A 依赖 A 自己,只要产生了依赖关系的闭环, 即造成了循环依赖。
那么,循环依赖会引发什么问题呢?理解这个问题先得理解 Bean 的生命周期,以下先回顾下

Bean的生命周期回顾

1. 启动容器:加载 Bean
2. 实例化 Bean 对象
3. 依赖注入:装配 Bean 的属性
4. 初始化 Bean :执行 aware 接口方法、预初始化方法、初始化方法、后初始化方法
5. 关闭容器:销毁 Bean
在以上第四个步骤执行完毕,才算一个初始化完成的 Bean ,也即 Spring 容器中完整的 Bean 对象。

循环依赖的问题

Spring 容器保存 Bean 的方式,是采取缓存的方式:使用 Map<String, Object> 的结构, key Bean
的名称, value Bean 对象。需要使用时直接从缓存获取。
假如 A B 互相依赖(循环依赖):
1. 容器中没有 A 对象,实例化 A 对象
2. 装配 A 中的 B 对象,发现 B 在容器中没有,需要先实例化 B
3. 实例化 B 对象
4. 装配 B 中的 A 对象,发现 A 在容器中没有,需要先实例化 A
5. 重复第一个步骤
这就套娃了 , 你猜是先 StackOverflow 还是 OutOfMemory
Spring 怕你不好猜,就先抛出了 BeanCurrentlyInCreationException
[PS]
  • Bean会依赖某些注入的Bean来完成初始化工作
  • 由于Spring支持构造方法注入,属性/Setter注入的方式,所以不能简单的先把所有对象全部实例化,放到缓存中,再全部执行初始化。原因很简单,此时所有对象的引用都可以获取到,但属性都null,执行初始化甚至构造方法都可能出现空指针异常。
那么我们说 Spring 能解决循环依赖,也不是所有的情况都可以解决,只有以下情况才支持。

Spring支持的循环依赖

Spring 容器中注册循环依赖的 Bean ,必须是单例模式,且依赖注入的方式为属性注入。
原型模式及构造方法注入的方式,不支持循环依赖。以下为说明:
  • 原型模式(prototype)的Bean:原因很好理解,创建新的A时,发现要注入原型字段B,又创建新B发现要注入原型字段A... 还是典型的套娃行为...
  • 基于构造器的循环依赖,就更不用说了,官方文档都摊牌了,你想让构造器注入支持循环依赖,是不存在的,不如把代码改了。
那么默认单例的属性注入场景, Spring 是如何支持循环依赖的?

Spring解决循环依赖

Spring 是使用三级缓存的机制来解决循环依赖问题,以下为三级缓存的定义:

 三级缓存的源码见 DefaultSingletonBeanRegistry

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
SingletonBeanRegistry {
/** Cache of singleton objects: bean name to bean instance. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>
(256);
/** Cache of singleton factories: bean name to ObjectFactory. */
private final Map<String, ObjectFactory<?>> singletonFactories = new
HashMap<>(16);
/** Cache of early singleton objects: bean name to bean instance. */
private final Map<String, Object> earlySingletonObjects = new
ConcurrentHashMap<>(16);
}
以下是部分说明:
  • 三级缓存singletonFactories中保存的是ObjectFactory对象(Bean工厂),其中包含了 BeanNameBean对象,RootBeanDefinition,该工厂可以生成Bean对象。
  • 由于Bean可能被代理,此时注入到其他Bean属性中的也应该是代理Bean
单例模式的 A B 循环依赖执行流程如下:

为什么要使用三级缓存

依照以上三级缓存的流程,其实使用二级缓存也能满足循环依赖的注入:
  • 普通的IoC容器使用一级缓存即可,但无法解决循环依赖问题。
  • 解决循环依赖问题:使用二级缓存即可。一级缓存保存完整Bean,二级缓存保存提前曝光的不完 整的Bean
  • 需要AOP代理Bean时,有两种实现思路:                                                                             (1)再加一级缓存                                                                                                                     (2)只使用二级缓存,其中二级缓存保存Bean的代理对象,代理对象中引用不完整的原始对象即可。
  • Spring使用三级缓存保存ObjectFactoryBean工厂,在代码的层次设计及扩展性上都会更好。 psObjectFactory内部可以根据 SmartInstantiationAwareBeanPostProcessor 这样的后置处 理器获取提前曝光的对象。

九、AOP的理解

AOP Aspect-Oriented Programming ):面向切面编程。对多个业务代码横切来实现统一的业务管理,而不用侵入业务代码本身。这样面向切面的编程思想就是AOP
使用场景:日志记录,事务管理,性能统计,安全控制,异常处理等
优点:代码解耦,统一业务功能对具体业务无侵入性,这样可扩展性更好,灵活性更高
SpringAOP 是采取动态代理的方式,具体是基于 JDK CGLIB 两种:
  • JDK动态代理:需要被代理类实现接口,使用 InvocationHandler Proxy 动态的生成代理类
  • CGLIB动态代理:需要被代理类能被继承,不能被final修饰。使用 MethodInterceptor 来对方法拦截。CGLIB底层是基于ASM字节码框架,在运行时动态生成代理类
SpringAOP 如何使用: @Aspect 定义切面,并注册到容器中,使用 @Pointcut 定义好切点方法后,可以对目标方法进行拦截:
  • 前置通知    使用@Before:通知方法会在目标方法调用之前执行。
  • 后置通知    使用@After:通知方法会在目标方法返回或者抛出异常后调用。
  • 返回之后通知    使用@AfterReturning:通知方法会在目标方法返回后调用。
  • 抛异常后通知    使用@AfterThrowing:通知方法会在目标方法抛出异常后调用。
  • 环绕通知    使用@Around:通知包裹了被通知的方法,在被通知的方法通知之前和调用之后执行自定义的行为。

十、Spring事务中的隔离级别有哪几种?

TransactionDefinition 接口中定义了五个表示隔离级别的常量:
  • ISOLATION_DEFAULT:使用后端数据库默认的隔离级别,Mysql默认采用的REPEATABLE_READ 隔离级别;Oracle默认采用的READ_COMMITTED隔离级别。
  • ISOLATION_READ_UNCOMMITTED:最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
  • ISOLATION_READ_COMMITTED:允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
  • ISOLATION_REPEATABLE_READ:对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
  • ISOLATION_SERIALIZABLE:最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

十一、Spring事务中有哪几种事务传播行为?

TransactionDefinition 接口中定义了七个表示事务传播行为的常量。
支持当前事务的情况:
  • PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
  • PROPAGATION_SUPPORTS: 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
  • PROPAGATION_MANDATORY: 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)。
不支持当前事务的情况:
  • PROPAGATION_REQUIRES_NEW: 创建一个新的事务,如果当前存在事务,则把当前事务挂起。
  • PROPAGATION_NOT_SUPPORTED: 以非事务方式运行,如果当前存在事务,则把当前事务挂起。
  • PROPAGATION_NEVER: 以非事务方式运行,如果当前存在事务,则抛出异常。
其他情况:
  • PROPAGATION_NESTED: 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于PROPAGATION_REQUIRED

 12.SpringMVC的流程

SpringMVC 的请求响应步骤如下:
具体步骤:
  • 第一步:(发起)发起请求到前端控制器(DispatcherServlet)
  • 第二步:(查找)前端控制器请求HandlerMapping查找 Handler(可以根据xml配置、注解进行查找)
  • 第三步:(返回)处理器映射器HandlerMapping向前端控制器返回HandlerHandlerMapping 会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象,多HandlerInterceptor拦截器对象),通过这种策略模式,很容易添加新的映射策略
  • 第四步:(调用)前端控制器调用处理器适配器去执行Handler
  • 第五步:(执行)处理器适配器HandlerAdapter将会根据适配的结果去执行Handler
  • 第六步:(返回Handler执行完成给适配器返回ModelAndView
  • 第七步:(接收)处理器适配器向前端控制器返回ModelAndView ModelAndView
  • SpringMVC框架的一个底层对象,包括 Modelview
  • 第八步:(解析)前端控制器请求视图解析器去进行视图解析 (根据逻辑视图名解析成真正的视图 (jsp)),通过这种策略很容易更换其他视图技术,只需要更改视图解析器即可
  • 第九步:(返回)视图解析器向前端控制器返回View
  • 第十步:(渲染)前端控制器进行视图渲染 (视图渲染将模型数据(ModelAndView对象中)填充request域)
  • 第十一步:(响应)前端控制器向用户响应结果
以下是对出现的一些组件的介绍:
(1) 前端控制器 DispatcherServlet (不需要程序员开发)。
作用:接收请求,响应结果,相当于转发器,中央处理器。有了 DispatcherServlet 减少了其它组件之间
的耦合度。
(2) 处理器映射器 HandlerMapping (不需要程序员开发)。
作用:根据请求的 url 查找 Handler
(3) 处理器适配器 HandlerAdapter (不需要程序员开发)。
作用:按照特定规则( HandlerAdapter 要求的规则)去执行 Handler
(4) 处理器 Handler (需要程序员开发)。
注意:编写 Handler 时按照 HandlerAdapter 的要求去做,这样适配器才可以去正确执行 Handler
(5) 视图解析器 ViewResolver (不需要程序员开发)。
作用:进行视图解析,根据逻辑视图名解析成真正的视图( view
(6) 视图 View (需要程序员开发 jsp )。
注意: View 是一个接口,实现类支持不同的 View 类型( jsp freemarker pdf…
ps: 不需要程序员开发的,需要程序员自己做一下配置即可。

十三、Mybatis中,#{}${}的区别

  • #{变量名} 是预处理替换的方式,本质是 jdbc 中占位符的替换。如传入字符串,会替换为带单引号的值。可以安全性更好,
  • ${变量名} 是字符串的替换,只是对 sql 字符串进行拼接。如传入字符串,会直接替换为字符串的值,不加单引号。
# 的方式可以很大程度的防止 sql 注入,相对来说更安全。而 $ 的方式不能。

十四、Mybatis中如何一对一、一对多关联

十五、SpringBoot 自动配置原理

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

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

相关文章

【转】金融行业JR/T0197-2020《金融数据安全 数据安全分级指南》解读

原文链接&#xff1a;金融行业JR/T0197-2020《金融数据安全 数据安全分级指南》解读 《金融数据安全 数据安全分级指南》 解 读 随着IT技术的发展&#xff0c;银行的基础业务、核心流程等众多事务和活动都运营在信息化基础之上&#xff0c;金融机构运行过程中产生了大量的数字…

词嵌入、情感分类任务

目录 1.词嵌入&#xff08;word embedding&#xff09; 对单词使用one-hot编码的缺点是难以看出词与词之间的关系。 所以需要使用更加特征化的表示&#xff08;featurized representation&#xff09;&#xff0c;如下图所示&#xff0c;我们可以得到每个词的向量表达。 假设…

IO(JavaEE初阶系列8)

目录 前言&#xff1a; 1.文件 1.1认识文件 1.2结构和目录 1.3文件路径 1.4文本文件vs二进制文件 2.文件系统的操作 2.1Java中操作文件 2.2File概述 2.2.1构造File对象 2.2.2File中的一些方法 3.文件内容的操作 3.1字节流 3.1.1InPutStream的使用方法 3.1.2OutPu…

windows下安装anaconda、pycharm、cuda、cudnn、PyTorch-GPU版本

目录 一、anaconda安装及虚拟环境创建 1.anaconda的下载 2.Anaconda的安装 3.创建虚拟环境 3.1 环境启动 3.2 切换镜像源 3.3环境创建 3.4 激活环境 3.5删除环境 二、pycharm安装 1.pycharm下载 2.pycharm的安装 三、CUDA的安装 1.GPU版本和CUDA版本、cudnn版本、显卡…

一起学算法(二维数组篇)

1.概念定义 1.矩阵的定义 矩阵A(nm)的定义时按照长方形排列的复数或实数集合&#xff0c;其中n代表的是行数&#xff0c;m代表的是列数。如下所示&#xff0c;代表的是一个4x3的矩阵 在Java中&#xff0c;我们可以用A[n][m]来代表一个n*m的矩阵&#xff0c;其中A[i][j]代表的是…

python:基于Kalman滤波器的移动物体位置估计

CSDN@_养乐多_ Kalman滤波器是一种经典的估计方法,广泛应用于估计系统状态的问题。本篇博客将介绍Kalman滤波器的基本原理,并通过一个简单的Python代码示例,演示如何使用Kalman滤波器来估计移动物体的位置。 通过运行代码,我们将得到一个包含两个子图的图像,分别展示了估…

第二十二篇:思路拓展:如何打造高性能的 React 应用?

React 应用也是前端应用&#xff0c;如果之前你知道一些前端项目普适的性能优化手段&#xff0c;比如资源加载过程中的优化、减少重绘与回流、服务端渲染、启用 CDN 等&#xff0c;那么这些手段对于 React 来说也是同样奏效的。 不过对于 React 项目来说&#xff0c;它有一个区…

Ubuntu 23.04 作为系统盘的体验和使用感受

1.为啥主系统装了Ubuntu 由于公司发电脑了&#xff0c;我自己也有一台台式电脑&#xff0c;然后也想去折腾一下Ubuntu&#xff0c;就把自己的笔记本装成Ubuntu系统了&#xff0c; 我使用的是23.04的桌面版&#xff0c;带图形化界面的。我准备换回Windows 11了&#xff08;因为…

策略模式(Strategy)

策略模式是一种行为设计模式&#xff0c;就是定义一系列算法&#xff0c;然后将每一个算法封装起来&#xff0c;并使它们可相互替换。本模式通过定义一组可相互替换的算法&#xff0c;实现将算法独立于使用它的用户而变化。 Strategy is a behavioral design pattern that def…

Redis 如何解决缓存雪崩、缓存击穿、缓存穿透难题

前言 Redis 作为一门热门的缓存技术&#xff0c;引入了缓存层&#xff0c;就会有缓存异常的三个问题&#xff0c;分别是缓存击穿、缓存穿透、缓存雪崩。我们用本篇文章来讲解下如何解决&#xff01; 缓存击穿 缓存击穿: 指的是缓存中的某个热点数据过期了&#xff0c;但是此…

React Native获取手机屏幕宽高(Dimensions)

import { Dimensions } from react-nativeconsole.log(Dimensions, Dimensions.get(window)) 参考链接&#xff1a; https://www.reactnative.cn/docs/next/dimensions#%E6%96%B9%E6%B3%95 https://chat.xutongbao.top/

Python3 处理PDF之PyMuPDF 入门

PyMuPDF 简介 PyMuPDF是一个用于处理PDF文件的Python库&#xff0c;它提供了丰富的功能来操作、分析和转换PDF文档。这个库的设计目标是提供一个简单易用的API,使得开发者能够轻松地在Python程序中实现PDF文件的各种操作。 PyMuPDF的主要特点如下&#xff1a; 跨平台兼容性&a…

C++20 协程(coroutine)入门

文章目录 C20 协程&#xff08;coroutine&#xff09;入门什么是协程无栈协程和有栈协程有栈协程的例子例 1例 2 对称协程与非对称协程无栈协程的模型无栈协程的调度器朴素的单线程调度器让协程学会等待Python 中的异步函数可等待对象M:N 调度器——C# 中的异步函数 小结 C20 中…

替换开源LDAP,西井科技用宁盾目录统一身份,为业务敏捷提供支撑

客户介绍 上海西井科技股份有限公司成立于2015年&#xff0c;是一家深耕于大物流领域的人工智能公司&#xff0c;旗下无人驾驶卡车品牌Q-Truck开创了全球全时无人驾驶新能源商用车的先河&#xff0c;迄今为止已为全球16个国家和地区&#xff0c;120余家客户打造智能化升级体验…

SNAT和DNAT原理与应用

iptables的备份和还原 1.写在命令行当中的都是临时配置。 2.把我们的规则配置在 备份&#xff08;导出&#xff09;&#xff1a;iptables-save > /opt/iptables.bak 默认配置文件&#xff1a;/etc/sysconfig/iptables 永久配置&#xff1a;cat /opt/iptables.bak > /etc…

并查集练习—省份数量

上一篇中讲了并查集及其原理&#xff0c;在这篇文章中简单应用一下。如果对并查集不是很了解强烈建议先看上一篇。 题目&#xff1a; 有 n 个城市&#xff0c;其中一些彼此相连&#xff0c;另一些没有相连。如果城市 a 与城市 b 直接相连&#xff0c;且城市 b 与城市 c 直接相…

DP-GAN损失

在前面我们看了生成器和判别器的组成。 生成器损失公式&#xff1a; 首先将fake image 和真实的 image输入到判别器中&#xff1a; 接着看第一个损失&#xff1a;参数分别为fake image经过判别器的输出mask&#xff0c;和真实的label进行损失计算。对应于&#xff1a; 其中l…

捕捉时刻:将PDF文件中的图像提取为个性化的瑰宝(从pdf提取图像)

应用场景&#xff1a; 该功能的用途是从PDF文件中提取图像。这在以下情况下可能会很有用&#xff1a; 图片提取和转换&#xff1a;可能需要将PDF文件中的图像提取出来&#xff0c;并保存为单独的图像文件&#xff0c;以便在其他应用程序中使用或进行进一步处理。例如&#xff…

恺英网络宣布:与华为鸿蒙系统展开合作,将开发多款手游

8月5日消息&#xff0c;恺英网络宣布旗下子公司盛和网络参加了华为开发者大会&#xff08;HDC.Together&#xff09;游戏服务论坛&#xff0c;并在华为鸿蒙生态游戏先锋合作启动仪式上进行了亮相。恺英网络表示&#xff0c;将逐步在HarmonyOS上开发多款游戏&#xff0c;利用Har…

JVM 调优

点击下方关注我&#xff0c;然后右上角点击...“设为星标”&#xff0c;就能第一时间收到更新推送啦~~~ JVM调优是一项重要的任务&#xff0c;可以提高Java应用程序的性能和稳定性。掌握JVM调优需要深入了解JVM的工作原理、参数和配置选项&#xff0c;以及历史JVM参数的调整和优…