Java开发各种面试题(详情加答案)

一、Servlet技术特点

功能强大

Servlet既拥有Java提供的API,而且还可以调用Servlet封装的ServletAPI编程接口,因此,它在业务功能方面十分强大。

可移植

Servlet继承了Java语言的优点,程序一次编码,多平台运行,拥有超强的可移植性。

性能高效

如果存在多个请求,Servlet不会再被实例化,仍然由此Servlet对其进行处理。每一个请求是一个线程,而不是一个进程,因此,Servlet对请求处理的性能是十分高效的。

安全性高

Servlet使用了Java的安全框架,同时Servlet容器还可以为Servlet提供额外的功能,它的安全性是非常高的。

可扩展

它继承了Java的面向对象的优点。在业务逻辑处理中,可以通过封装、继承等来扩展实际的业务需要,其扩展性非常强。

二、Servlet与JSP的区别

1、角色不同

JSP页面可以存在HTML代码与Java代码并存的情况,而Servlet需要承担客户请求与业务处理的中间角色,只有调用固定的方法才能将动态内容输出为静态的HTML,所以,JSP更具有显示层的角色。

2、编程方法不同

使用Servlet开发Web应用程序需要遵循Java的标准,而JSP需要遵循一定脚本语言规范。

3、Servlet需要编译后进行

Servlet需要在Java编译器编译后才可以运行,JSP由JSP Container对其进行管理,所以无论JSP文件被创建还是修改,都不需要对其编译即可执行。

4、速度不同

在每次执行不同内容的动态JSP页面时,JSP Container都要对其自动编译,所以,它的效率低于Servlet的执行效率。

三、string可以继承吗?

不可以,因为String类有final修饰符,⽽final修饰的类是不能被继承的

四、springboot和springcloud区别有:

1、Spring Boot专注于快速方便的开发单个服务;Spring Cloud 关注的是多个服务之间的协调管理,

为各个服务提供配置,服务发现,断路器,路由,微代理等一系列集成服务。

2.SpringBoot可以离开SpringCloud独立开发项目,但SpringCloud不能够离开SpringBoot,

属于依赖关系SpringBoot专注于快速方便的开发微服务个体SpringCloud关全局的服务治理

五、xml的解析方式

1、dom解析方式

2、sax解析

3、jdom解析

4、dom4j解析

六、同步的方法

synchronized和lock锁

七、JVM、JRE和JDK的区别:

JVM(Java Virtual Machine):java虚拟机,用于保证java的跨平台的特性。

JRE(Java Runtime Environment):java的运行环境,包括jvm+java的核心类库。

JDK(Java Development Kit):java的开发工具,包括jre+开发工具

大小关系:JDK>JRE>JVM.

八、servlet和jsp的区别

jsp在本质上就是servlet jsp是Servlet的一种简化 servlet服务端接受请求 响应请求, jsp用来展示与接受客户端传递给后端的数据。

九、接口和抽象类的区别

 1.定义:抽象类是一个类,可以有普通方法和抽象方法,其中抽象方法必须被子类实现;接口是一组抽象方法的集合,所有方法都是抽象方法,且没有具体实现。

  2.实现:子类只能继承一个抽象类,但可以实现多个接口。

  3.构造函数:抽象类可以有构造函数,接口没有构造函数。

  4.变量:抽象类可以有变量,接口只能定义常量。

  5.访问控制:抽象类中的方法可以是public、protected和default访问控制,而接口中的方法默认是public。

  6.默认实现:抽象类可以有普通方法的默认实现,而接口中所有的方法都没有默认实现。

  7.继承:子类继承抽象类时必须实现其中的抽象方法,否则该子类也必须是抽象类;子类实现接口时必须实现其中的所有方法。

十、int 和Integer 的区别

1.Integer是int的包装类,int则是java的⼀种基本的数据类型;

2.Integer变量必须实例化之后才能使⽤,⽽int变量不需要实例化;

3.Integer实际是对象的引⽤,当new⼀个Integer时,实际上⽣成⼀个指针指向对象,⽽int则直接存储数值

4.Integer的默认值是null,⽽int的默认值是0。

十一、日志框架的常用种类:log4j、logback、log4j2

十二、多线程三大特性:

1、原子性保证数据的一致性、

2、可见性、一个线程修改的共享变量对其他线程可见

3、有序性 线程之间执行有顺序

十三、Spring中IOC和DI

IOC:控制反转,指的是对象的创建和生命周期的管理,全部托管给Spring容器,而传统对象的创建都是通过业务方使用关键字new或反射来创建的;控制反转是把控制权从业务方交给了Spring容器,这样做的最大好处就是实现解耦和面向接口编程。

DI:依赖注入,指的是获得依赖对象的过程由自身管理变为由IOC容器主动注入

十四、数据库怎么优化

1、优化sql语句

2、添加索引

3、分表技术

4、表设计合理化

5、读写分离

6、储存过程

7、配置优化

8、服务器硬件升级

9、定时清理不需要的数据

十五、xml是什么以及作用

xml是可扩展标记语言的意思,用于进行存储数据和传输数据,作为软件的配置文件

XML的使用场景:XML内容经常被当成消息进行网络传输,或者作为配置文件用于存储系统的信息。

十六、线程的五种状态

1、新建状态,线程创建时的状态

2、就绪状态,当线程调用start()方法时,线程等待cpu分配资源进入就绪状态

3、运行状态,线程获得CPU资源后,进入运行状态,真正开始执行run()方法。

4、阻塞状态,线程运行过程中,可能由于各种原因进入阻塞状态:

①线程通过调用sleep方法进入睡眠状态;

②线程调用一个在I/O上被阻塞的操作,即该操作在输入输出操作完成之前不会返回到它的调用者;

③线程试图得到一个锁,而该锁正被其他线程持有;

④线程在等待某个触发条件;

(1) 调用sleep(毫秒数),使线程进入"睡眠"状态。在规定的时间内,这个线程是不会运行的。

(2) 用suspend()暂停了线程的执行。除非线程收到resume()消息,否则不会返回"可运行"状态。

(3) 用wait()暂停了线程的执行。除非线程收到nofify()或者notifyAll()消息,否则不会变成"可运行"(是的,这看起来同原因2非常相象,但有一个明显的区别是我们马上要揭示的)。

(4) 线程正在等候一些IO(输入输出)操作完成。

(5) 线程试图调用另一个对象的"同步"方法,但那个对象处于锁定状态,暂时无法使用。

5、死亡状态,线程运行完毕或者报错没有处理

十七、对JVM的了解

java虚拟机,用于保证java的跨平台的特性。

作用

1. 字节码的解释执行:JVM能够将Java源代码编译成字节码,并解释执行。

  2. 内存管理:JVM负责管理Java程序的内存使用,包括分配内存、垃圾回收等操作。

  3. 安全管理:JVM通过安全管理器对Java应用程序进行安全审查,保证程序在执行时不会对系统产生危害。

十八、常见的注入攻击以及sql注入解决方案

SQL 注入: 通过在 SQL 语句中注入恶意代码来执行不受信任的操作,以获取敏感数据或者篡改数据。

解决方案1:PreparedStatement具有预编译功能

解决方案2:mybatis中#{}表达式防止SQL注入与PreparedStatement类似,都是对SQL语句进行预编译处理

解决方案3:对请求参数的敏感词汇进行过滤

解决方案4:nginx反向代理防止SQL注入

命令注入: 攻击者将能够执行不受信任的操作的命令注入到应用程序中。

LDAP 注入: 利用 LDAP 查询中的漏洞来获取敏感信息或者更改应用程序的行为4。

OS 注入: 利用操作系统的漏洞,向服务器输入不受信任的数据,以利用操作系统上的缺陷来执行可疑操作。

XML 注入: 利用 XML 编辑器中的漏洞创建恶意 XML 代码的攻击

十九、泛型是什么意思

泛型本质是指类型参数化。意思是允许在定义类、接口、方法时使用类型参,

当使用时指定具体类型,所有使用该泛型参数的地方都被统一化,保证类型一致。如果未指定具体类型,默认是Object类型。集合体系中的所有类都增加了泛型,泛型也主要用在集合

二十、maven的作用

1、在文件中添加相应的配置,maven就会自动的下载相应的jar包和依赖;

2、可以直接通过它打包war或者jar项目。

关于http

超文本传输协议,用于从万维网服务器传输超文本到本地浏览器的传送协议。

二十一、http作用

协议:计算机之间交流通信的一种规范 HTTP由一系列规则组成,客户端和服务器需要正确的处理这些规则

传输:可以理解为把一堆东西从A搬到B,或者从B搬到A

超文本:HTTP传输的内容就是超文本

1、文本:在互联网最早期的时候只是见到的字符文本,但现在文本的含义已经可以扩展到图片、视频、压缩包等,在HTTP眼里都算做文本

2、超文本:就是超越了普通文本的文本,它是文字、图片、视频等的混合体,最关键的是有超链接,能从一个超文本跳转到另外一个超文本

二十二、http工作原理

客户端与服务器建立连接

客户端向服务器发送请求

服务器接收请求,并根据请求返回响应的文件作为应答

客户端与服务器断开连接

二十三、http常见页面错误

400 (错误请求) 服务器不理解请求的语法。

401 (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。

403 (禁止) 服务器拒绝请求。

404 (未找到) 服务器找不到请求的网页。

405 (方法禁用) 禁用请求中指定的方法。

406 (不接受) 无法使用请求的内容特性响应请求的网页。

407 (需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。

408 (请求超时) 服务器等候请求时发生超时。

409 (冲突) 服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。

410 (已删除) 如果请求的资源已永久删除,服务器就会返回此响应。

411 (需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。

412 (未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。

413 (请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。

414 (请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。

415 (不支持的媒体类型) 请求的格式不受请求页面的支持。

416 (请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。

417 (未满足期望值) 服务器未满足"期望"请求标头字段的要求。

500 (服务器内部错误) 服务器遇到错误,无法完成请求。

501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。

502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。

503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。

504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。

505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。

二十四、八大基本数据类型

0

八大基本数据类型包装类

0

二十五、 基本数据类型和包装类型的区别:

1、包装类是对象,有⽅法和字段,对象的调⽤是通过引⽤对象的地址,⽽基本类型不是。

2、包装类型是引⽤的传递,基本类型是值的传递。

3、初始值不同:int的初始值位0,boolean的初始值为false;包装类型的初始值null。

4、声明的⽅式不同:基本类型不需要new关键字;包装类型需要new关键字创建对象分配内存空间。

5、存储位置不同:基本数据类型直接将值保存在堆中;包装类型的对象存储在堆中,通过对象的引⽤来调⽤。

6、使⽤的⽅式不同:基本数据类型直接赋值就可以;包装类型通常是在集合时使⽤。

二十六、装箱和拆箱的区别

概念:装箱是将值类型装换成引用类型;拆箱就是将引用类型转换成值类型;

就是把基本数据类型转换成包装类型,拆箱就是包装类型转变量值类型

0

二十七、 SpringBoot执行流程

1、启动SpringBoot的main时

2、然后拉起一个内置的tomcat

3、初始化一个Spring容器,自动的配置web.xml、applicationContext-*.xml配置文件

4、扫描@SpringBootApplication注解所在的类对应的所有包下的类,并交给Spring管理。

二十八、SpringBoot三大核心注解

1、@Configuration:用来代替 applicationContext.xml 配置文件

2、@EnableAutoConfiguration 开启自动配置,该注解会使springboot根据项目中依赖的jar包自动配置项目的配置项

3、@ComponentScan 开启组件扫描,该注解会自动扫描包路径下面的所有@Controller、@Service、@Repository、@Component的类,

不配置包路径的话,在springboot中默认扫描@SpringBootApplication所在类的同级目录以及子目录下的相关注解。

SpringBoot常用注解大全

0

二十九、SpringMVC

什么是MVC

MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范。

是将业务逻辑、数据、显示分离的方法来组织代码。

MVC主要作用是降低了视图与业务逻辑间的双向偶合。

MVC不是一种设计模式,MVC是一种架构模式。当然不同的MVC存在差异。

Model(模型):数据模型,提供要展示的数据,因此包含数据和行为,可以认为是领域模型或JavaBean组件(包含数据和行为),不过现在一般都分离开来:Value Object(数据Dao) 和 服务层(行为Service)。也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据和业务。

1、处理业务逻辑

2、保存数据的状态

View(视图):负责进行模型的展示,一般就是我们见到的用户界面,客户想看到的东西。

Controller(控制器):接收用户请求,委托给模型进行处理(状态改变),处理完毕后把返回的模型数据返回给视图,由视图负责展示。也就是说控制器做了个调度员的工作。

1、取得表单数据

2、调用业务逻辑

3、转向指定的页面

MVC框架要做哪些事情

1、将url映射到java类或java类的方法 .

2、封装用户提交的数据 .

3、处理请求--调用相关的业务处理--封装响应数据 .

4、将响应的数据进行渲染 . jsp / html 等表示层数据

Spring MVC的特点:

1、轻量级,简单易学

2、高效 , 基于请求响应的MVC框架

3、与Spring兼容性好,无缝结合

4、约定优于配置

5、功能强大:RESTful、数据验证、格式化、本地化、主题等

6、简洁灵活

执行流程

1.发送请求

DispatcherServlet 前端控制器是 SpringMVC 的核心组件之一,它接收客户端的请求并将请求分派到对应的处理器(Handler)进行处理。在接收到请求后,DispatcherServlet 会将请求 URL 传递给 HandlerMapping 映射器进行处理,并根据请求 URL 匹配对应的 HandlerExecutionChain 处理器执行链。HandlerExecutionChain 包含了一个或多个 Interceptor 拦截器和一个 Handler 处理器,拦截器可以在请求处理前后进行一些额外的处理,而 Handler 则负责具体的业务处理。

2.处理器执行

DispatcherServlet前端控制器请求HandlerAdapter适配器执行Handler处理器,HandlerAdapter 适配器是 SpringMVC 中用于执行处理器(Handler)的重要组件。在 HandlerMapper 映射器确定了需要执行的 Handler 处理器之后,HandlerAdapter 就负责根据具体的 Handler 处理器类型,调用相应的方法进行处理。不同的 Handler 处理器类型通常需要不同的处理方式,因此需要不同的 HandlerAdapter 适配器实现来进行适配。

3.返回处理结果

在 HandlerAdapter 适配器执行完 Handler 处理器后,会获得一个 ModelAndView 对象,它包含了处理结果视图的名称和需要在视图中使用的模型数据。这个 ModelAndView 对象将被返回给 DispatcherServlet 前端控制器,以便进行下一步的处理。

4.处理视图

DispatcherServlet请求ViewResolver对ModelAndView进行视图解析,ViewResolver 视图解析器是 SpringMVC 中用于将 ModelAndView 解析为具体视图对象(View)的组件。视图解析器可以根据指定的视图名,通过配置的 ViewResolver 实现类查找对应的视图对象。常用的 ViewResolver 实现类有 InternalResourceViewResolver 等,它们都可以将 ModelAndView 中指定的视图名解析为 JSP 视图对象。

5.处理结果

在经过 ViewResolver 视图解析器的处理后,ModelAndView 对象将被解析为对应的 View 视图对象,即用于渲染视图的具体组件。View 组件可以是 JSP 视图、FreeMarker 模板、JSON 数据等不同形式的响应内容。

6.返回响应

最后一步是前端控制器 DispatcherServlet 对视图对象进行渲染。具体的渲染方式会根据 View 类型的不同而有所差异,例如 JSP 视图的渲染方式需要使用 Servlet API 和 JSP 引擎。渲染完成后,前端控制器将生成的响应数据返回给客户端浏览器进行展示。

关于Mybatis

用一句话来形容什么Mybatis:MyBatis 是一个可以自定义 SQL、存储过程和高级映射的持久层框架。Mybatis是一个半ORM(对象关系映射)框架,底层封装了JDBC,是程序员在开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等

三十、Mybatis相对JDBC的优势:

1、Mybatis是把连接数据库的信息都是写在配置文件中,因此不存在硬编码问题,方便后期维护。

2、Mybatis执行的SQL语句都是通过配置文件进行配置,不需要写在Java代码中。

3、Mybatis的连接池管理、缓存管理等让连接数据库和查询数据效率更高。

三十一、Mybatis的特点及优缺点

特点:

1、MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。

2、MyBatis 封装了底层 JDBC API 的调用细节,并能自动将结果集转换成 Java Bean对象,大大简化了 Java 数据库编程的重复工作。

3、MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。

4、MyBatis 可以使用简单的XML或注解用于配置和原始映射,将接口和Java的实体映射成数据库中的记录。

5、MyBatis 把 SQL语句从 Java 源程序中独立出来,放在单独的 XML 文件中编写,给程序的维护带来了很大便利。

6、MyBatis 需要程序员自己去编写 SQL语句,程序员可以结合数据库自身的特点灵活控制 SQL语句,因此能够实现比 Hibernate 等全自动 ORM框架更高的查询效率,能够完成复杂查询。

优点:

1、简单易学,Mybatis本身就很小且简单,整个源代码大概5MB左右。并且没有任何第三方依赖,简单实用只要几个Jar包+配置几个SQL映射文件,而且有官方中文文档,可以通过官方文档轻松学习。

2、使用灵活,易于上手和掌握。相比于JDBC需要编写的代码更少,减少了50%以上的代码量。

3、提供XML标签,支持编写动态SQL,满足不同的业务需求。

4、SQL写在XML里,便于统一管理和优化,同时也解除SQL与程序代码的耦合。使系统的设计更清晰,更易维护,更易单元测试。SQL和代码的分离,提高了可维护性。

5、提供映射标签,支持对象与数据库的ORM字段关系映射。

6、提供对象关系映射标签,支持对象关系组建维护。

缺点:

1、SQL语句的编写工作量较大,尤其在表、字段比较多的情况下,对开发人员编写SQL的能力有一定的要求。

2、SQL语句依赖于数据库,导致数据库不具有好的移植性,不可以随便更换数据库

三十二、MyBatis的重要组件

1、Mybatis的配置文件:SqlMapConfig.xml是Mybatis的全局配置文件,主要配置数据源、事务、加载映射文件等,它的名称可以是任意(最好见名知意)。Mapper.xml主要是配置Statement的相关信息,如SQL语句。

2、SqlSessionFactoryBuilder:会根据XML配置或是Java配置来生成SqlSessionFactory对象.采用建造者模式(简单来说就是分步构建一个大的对象,例如建造一个大房子,采用购买砖头、砌砖、粉刷墙面的步骤建造,其中的大房子就是大对象,一系列的建造步骤就是分步构建)。

3、SqlSessionFactory:用于生成SqlSession,可以通过 SqlSessionFactory.openSession() 方法创建 SqlSession 对象。使用工厂模式(简单来说就是我们获取对象是通过一个类,由这个类去创建我们所需的实例并返回,而不是我们自己通过new去创建)。

4、SqlSession:相当于JDBC中的 Connection对象,可以用 SqlSession 实例来直接执行被映射的 SQL 语句,也可以获取对应的Mapper。

5、Executor:MyBatis 中所有的 Mapper 语句的执行都是通过 Executor 执行的。(Mapper:由XML文件和Java接口组成,根据XML中配置的映射信息执行对应的SQL语句并返回执行结果。)

6、Mapper接口:数据操作接口也就是通常说的 DAO 接口,要和 Mapper 配置文件中的方法一一对应,也就是必须和Mapper.xml中的增删改查标签Id一致。

7、Mapper配置:用于组织具体的查询业务和映射数据库的字段关系,可以使用 XML 格式(Mapper.xml)或 Java 注解格式来实现。

8、MappedStatement:作用是封装了Statement的相关信息,包括SQL语句、输入参数和输出结果等等。

三十三、MyBatis 执行流程

1、首先是加载Mybatis的全局配置文件,随后会加载SQL 映射文件或者是注解的相关 SQL 内容。

2、创建会话工厂,MyBatis 通过读取配置文件的信息来构造出会话工厂(SqlSessionFactory)。

3、创建会话,根据会话工厂,MyBatis 就可以通过它来创建会话对象(SqlSession),会话对象是一个接口,该接口中包含了对数据库操作的增、删、改、查方法。

4、创建执行器,因为会话对象本身不能直接操作数据库,所以它使用了一个叫做数据库执行器(Executor)的接口来帮它执行操作。

5、封装 SQL 对象,在这一步,执行器将待处理的 SQL 信息封装到一个对象中(MappedStatement),该对象包括 SQL 语句、输入参数映射信息(Java 简单类型、HashMap 或 POJO)和输出结果映射信息(Java 简单类型、HashMap 或 POJO)。

6、操作数据库,拥有了执行器和 SQL 信息封装对象就使用它们访问数据库了,最后再返回操作结果,结束流程。

三十四、MyBatis 基本概念

①、什么是“持久化”

持久(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的数据存储在关系型的数据库中,当然也可以存储在磁盘文件中、XML数据文件中等,但是一般都会存放在关系型数据库中如:MySQL、Oracle等。

②、什么是“持久层”

持久层(Persistence Layer),即专注于实现数据持久化应用领域的某个特定系统的一个逻辑层面,将数据使用者和数据实体相关联。比如我们的pojo层、Dao层和Service层的关联。

③、什么是“ORM”

ORM即Object-Relationl Mapping,意思为对象关系映射。它用于实现面向对象编程语言的类型 和 关系型数据库类型之间的相互转换。简单的说,ORM是通过描述对象和数据库之间映射的元数据,将程序中的对象与关系数据库相互映射,到时候我们在具体的操作数据库的时候,就不需要再去和复杂的SQL语句打交道,只要像平时操作对象一样操作它就可以了 。但是从前面的描述可知,我们的Mybatis是需要与SQL打交道的,所以我们认为Mybatis是一个半自动化的ORM框架。

ORM的方法论基于三个核心原则:

简单:以最基本的形式建模数据。

传达性:数据库结构被任何人都能理解的语言文档化。

精确性:基于数据模型创建正确标准化了的结构。

在Java中典型的ORM中有:

JPA:全称Java Persistence API,即Java持久化API,是sun公司推出的一套基于ORM的规范,内部由一系列的接口和抽象类构成。JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,是Java自带的框架。

Hibernate:全自动的ORM框架,强大、复杂、笨重、学习成本较高。Hibernate除了作为ORM框架之外,它也是一种JPA实现。

Mybatis:半自动的ORM框架,强大,简单,灵活,学习成本较低。Mybatis提供了自定义SQL,这样开发者将主要精力放在SQL上就行了。

三十五、Mybatis和Hibernate的区别

①、开发方面:

Hibernate 属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。

Mybatis 属于半自动 ORM 映射工具,Mybatis 在查询关联对象或关联集合对象时,需要手动编写 SQL来完成,所以,称之为半自动 ORM 映射工具。不过 Mybatis 可以通过 XML 或注解方式灵活配置要运行的 SQL语句,并将Java 对象和 SQL语句映射生成最终执行的 SQL,最后将 SQL执行的结果再映射生成Java 对象。

②、底层方面:

Hibernate的底层则是 JPA 规范的实现。

Mybatis的底层封装了 JDBC 的代码。

③、SQL优化方面:

Hibernate 自动生成SQL,有些语句较为繁琐,会多消耗一些性能。

Mybatis 手动编写SQL,可以避免不需要的查询,提高系统性能。

④、学习成本方面:

Hibernate 的学习门槛高,要精通门槛更高,而且怎么设计 O/R 映射,在性能和对象模型之间如何权衡,以及怎样用好 Hibernate 需要具有很强的经验和能力才行。

Mybatis的学习门槛低,简单易学,程序员只需要把重心放在写原生态 SQL 上即可,可严格控制 SQL执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。

⑤、对象管理方面

Hibernate 是完整的对象/关系映射的框架,对象/关系映射能力极强,开发工程中,无需过多关注底层实现,只要去管理对象即可;而且数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用 Hibernate 开发可以节省很多代码,提高效率。

Mybatis 需要自行管理 映射关系;而且Mybatis 无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套 SQL映射文件,工作量大。

⑥日志系统方面:

Hibernate日志系统非常健全,涉及广泛,包括:SQL记录、关系异常、优化警告、缓存提示、脏数据警告等。

Mybatis则除了基本记录功能外,功能薄弱很多。

⑦、缓存方面

相同点:

Hibernate和Mybatis的二级缓存除了采用系统默认的缓存机制外,都可以通过实现你自己的缓存或为其他第三方缓 存方案,创建适配器来完全覆盖缓存行为。

不同点:

Hibernate的二级缓存配置在SessionFactory生成的配置文件中进行详细配置,然后再在具体的表-对象映射中配置是那种缓存。如果使用二级缓存时如果出现脏数据,系统会报出错误并提示。

MyBatis的二级缓存配置都是在每个具体的表-对象映射中进行详细配置,这样针对不同的表可以自定义不同的缓存机制。并且Mybatis可以在命名空间中共享相同的缓存配置和实例,通过Cache-ref来实现。

⑧、各一句话总结它们:

Mybatis:小巧、方便、高效、简单、直接、半自动化。比喻:机械工具,使用方便,拿来就用,但工作还是要自己来作,不过工具是活的,怎么使由我决定。

Hibernate:强大、方便、高效、复杂、间接、全自动化。比喻:智能机器人,但研发它(学习、熟练度)的成本很高,工作都可以摆脱他了,但仅限于它能做的事。

三十六、BS和CS的区别

bs就是浏览器服务器架构(网站) ,对C/S架构的一种变化或者改进的架构。

cs就是需要安装的那些应用程序app, 客户端和服务器架构二者进行比较的话,有以下几点不同。

1、标准性:bs开发更标准一些,因为cs需要在不同的系统上执行,bs只需要在浏览器上执行

2、效率:cs效率更高,cs属于安装的软件,很多内容已经安装在电脑中了,只需要联网获取数据即可,而bs运行在浏览器上,所有的数据必须经过下载才能使用;

3、升级:bs无缝升级,cs需要删除老版本,再安装新版本

4、安全性:cs更为安全, 因为必须安装软件才能使用;bs安全度较低,只要有浏览器就可以使用

5、开发成本:cs开发成本更高,程序员必须精通各个系统;bs开发成本很低,只要浏览器能够正常运行即可

三十七、如何停止线程

1、stop() 方法可以直接停掉一个正在运行的线程,但是可能会引起一些问题

2、通过设置标志位来停止线程 这是一种通用的停止线程的方式。我们可以在程序中定义一个布尔型变量,用来表示线程是否需要继续执行。每次在线程体内部判断这个标志位,如果标志位为 false,则退出线程体即可

3、通过 interrupt() 方法停止线程 当一个线程调用 interrupt() 方法时,它会将自己标记为“已中断”,但不会实际停止执行。在后续的操作中,如果检测到自己被标记为已中断,我们就可以主动终止运行。

4、通过 wait()/notify() 方法停止线程 等待/通知机制是 Java 中常用的线程协作方式之一。我们可以在需要等待的位置上调用 wait() 方法,让线程进入等待状态,并在其他线程执行特定操作(例如修改变量值、发送信号等)后,再通过 notify() 或 notifyAll() 方法来唤醒这个线程继续执行。利用这个机制,我们也可以停止某个线程的运行。

停止线程注意事项

无论采用哪种方式,我们都应该注意以下事项:

1、在结束线程之前,应该尽可能地将它保持在一个稳定状态,以免出现异常或数据丢失等问题。

2、确保正确地释放资源,关闭流等操作,避免资源泄漏。

3、不要在 stop() 方法中执行过多的操作,否则容易导致死锁、阻塞等问题

程序员应该根据具体的需求和情况,选择合适的方式来停止线程,同时做好异常处理和资源释放等工作。

如何安全停止线程

1、 在线程中加入一个成员变量,当一个flag使用。在线程run()方法中轮流去检查这个变量,变量变化时就退出这个线程。

未知

三十八、 MVC模式 VS 三层架构

和 MVC 模式类似,三层架构同样将系统划分成了 3 层:

表示层(UI):用来实现与用户的交互,接收用户请求,并将请求交给业务逻辑层(BLL)和数据访问层(DAL)进行处理,最后将处理结果返回给用户。

业务逻辑层(BLL):起到承上启下的作用,接收表示层传递来的请求,并针对业务对数据进行处理,以实现业务目标。

数据访问层(DAL):用于实现与数据库的交互和访问,例如从数据库中获取数据、保存或修改数据库中的数据等。

三层架构和 MVC 模式中各层对应关系如下:

三层架构中的表示层(UI)包含 HTML、JSP 等前台页面以及后台的 Servlet,即它相当于 MVC 模式中的 View 层 + Controller 层。

三层架构中的业务逻辑层(BLL),则只包含了 Service 接口及其实现类(Servicelmpl)的代码,即它相当于 MVC 模式中 Model 层的一部分,并不包含 Dao 和实体类。

三层架构中的数据访问层(DAL),则只包含了 Dao 接口及其实现类(DaoImpl)的代码,即它相当于 MVC 模式中 Model 层的一部分,并不包含 Service 和实体类。

三十九、==和equals的区别

==是运算符,如果是基本数据类型,则比较存储的值;如果是引用数据类型,则比较所指向对象的地址值。

equals是Object的方法,比较的是所指向的对象的地址值,一般情况下,重写之后比较的是对象的值。

四十、什么情况使用==,什么情况使用equals

关于spring

Spring是一个分层的Java SE/EE应用一站式的轻量级开源框架。Spring核心是IOC和AOP。

四十一、什么是IOC

        控制反转,指将对象的控制权转移给Spring框架,由 Spring 来负责控制对象的生命周期(比如创建、销毁)和对象间的依赖关系。【对于某个具体的对象而言,以前是由自己控制它所引用对象的生命周期,而在IOC中,所有的对象都被 Spring 控制,控制对象生命周期的不再是引用它的对象,而是Spring容器,由 Spring 容器帮我们创建、查找及注入依赖对象,而引用对象只是被动的接受依赖对象,所以这叫控制反转。】

四十二、Spring的IOC理解,什么是依赖注入

Dependency Injection,依赖注入:在程序运行时,动态的向某个对象提供它所需要的其他对象。

【应用程序在运行时依赖 IoC 容器来动态注入对象所需要的外部依赖。而 Spring 的 DI 具体就是通过反射实现注入的,反射允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性】

四十三、IOC的原理

  Spring 的 IoC 的实现原理就是工厂模式加反射机制,而在 Spring 容器中,Bean 对象如何注册到 IoC 容器,以及Bean对象的加载、实例化、初始化。

四十四、Spring的AOP理解:面对切面编程

这是一种编程模式,他允许程序员通过自定义的横切点进行模块化,将那些影响多个类的行为封装到课重用的模块中。【例子:比如日志输出,不使用AOP的话就需要把日志的输出语句放在所有类中,方法 中,但是有了AOP就可以把日志输出语句封装一个可重用模块,在以声明的方式将他 们放在类中,每次使用类就自动完成了日志输出】

四十五、Spring 框架中都用到了哪些设计模式?

1.工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例;

2.单例模式:Bean默认为单例模式。

3.代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术;

4.模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。

5.观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现ApplicationListener。

四十六、有哪些不同类型的依赖注入实现方式?

依赖注入是时下最流行的IOC实现方式,依赖注入分为

1.接口注入(Interface Injection),【由于在灵活性和易用性比较差,现在从Spring4开始已被废弃】

2.Setter方法注入(Setter Injection),【构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系列参数,每个参数代表一个对其他类的依赖】

3.构造器注入(Constructor Injection)【Setter方法注入是容器通过调用无参构造器或无参static工厂 方法实例化bean之后,调用该bean的setter方法,即实现了基于setter的依赖注入】

四十七、Spring支持的几种bean的作用域

1.singleton : bean在每个Spring ioc 容器中只有一个实例。

2.prototype:一个bean的定义可以有多个实例。

3.request:每次http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效。

4.session:在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。

5.global-session:在一个全局的HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。

四十八、什么是bean的自动装配?

在Spring框架中,在配置文件中设定bean的依赖关系是一个很好的机制,Spring 容器能够自动装配相互合作的bean,这意味着容器不需要和配置,能通过Bean工厂自动处理bean之间的协作。这意味着 Spring可以通过向Bean Factory中注入的方式自动搞定bean之间的依赖关系。自动装配可以设置在每个bean上,也可以设定在特定的bean上。

四十九、spring 自动装配 bean 有哪些方式?

在spring中,对象无需自己查找或创建与其关联的其他对象,由容器负责把需要相互协作的对象引用赋予各个对象,使用autowire来配置自动装载模式

在Spring框架xml配置中共有5种自动装配:

1.no:默认的方式是不进行自动装配的,通过手工设置ref属性来进行装配bean

2.byName:通过bean的名称进行自动装配,如果一个bean的 property 与另一bean 的name 相同,就进行自动装配。

3.byType:通过参数的数据类型进行自动装配

4.constructor:利用构造函数进行装配,并且构造函数的参数通过byType进行装配。

5.autodetect:自动探测,如果有构造方法,通过 construct的方式自动装配,否则使用 byType的方式自动装配。

五十、使用@Autowired注解自动装配的过程是怎样的?

1、使用@Autowired注解来自动装配指定的bean。在使用@Autowired注解之前需要在Spring配置文件进行配置,。

2、在启动spring IOC时,容器自动装载了一个AutowiredAnnotationBeanPostProcessor后置处理器,当容器扫描到@Autowied、@Resource或@Inject时,就会在IOC容器自动查找需要的bean,并装配给该对象的属性。在使用@Autowired时,首先在容器中查询对应类型的bean:

1.如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据

2.如果查询的结果不止一个,那么@Autowired会根据名称来查找;

3.如果上述查找的结果为空,那么会抛出异常。解决方法时,使用required=false。

五十一、@Component, @Controller, @Repository, @Service 有何区别?

1、@Component:这将 java 类标记为 bean。它是任何 Spring 管理组件的通用构造型。spring 的组件扫描机制现在可以将其拾取并将其拉入应用程序环境中。

2、@Controller:这将一个类标记为 Spring Web MVC 控制器。标有它的 Bean 会自动导入到 IOC 容器中。

3、@Service:此注解是组件注解的特化。它不会对 @Component 注解提供任何其他行为。您可以在服务层类中使用 @Service 而不是 @Component,因为它以更好的方式指定了意图。

4、@Repository:这个注解是具有类似用途和功能的 @Component 注解的特化。它为 DAO 提供了额外的好处。它将 DAO 导入 IOC 容器,并使未经检查的异常有资格转换为 Spring DataAccessException。

五十二、@Autowired和@Resource之间的区别

1、@Autowired和@Resource可用于:构造函数、成员变量、Setter方法

2、@Autowired和@Resource之间的区别在于

3、@Autowired默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它required属性为false)。

4、@Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入。

五十三、Spring的事务传播行为

spring事务的传播行为说的是,当多个事务同时存在的时候,spring如何处理这些事务的行为

① propagation_required:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。

② propagation_supports:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。

③ propagation_mandatory:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。

④ propagation_requires_new:创建新事务,无论当前存不存在事务,都创建新事务。

⑤ PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

⑥ PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。

⑦ PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按REQUIRED属性执行。

五十四、spring 的事务隔离

spring 有五大隔离级别,默认值为 ISOLATION_DEFAULT(使用数据库的设置),其他四个隔离级别和数据库的隔离级别一致:

1、ISOLATION_DEFAULT:用底层数据库的设置隔离级别,数据库设置的是什么我就用什么;

2、ISOLATION_READ_UNCOMMITTED:未提交读,最低隔离级别、事务未提交前,就可被其他事务读取(会出现幻读、脏读、不可重复读);

3、ISOLATION_READ_COMMITTED:已提交读,一个事务提交后才能被其他事务读取到(会造成幻读、不可重复读),SQL server 的默认级别;

4、ISOLATION_REPEATABLE_READ:可重复读,保证多次读取同一个数据时,其值都和事务开始时候的内容是一致,禁止读取到别的事务未提交的数据(会造成幻读),MySQL 的默认级别;

5、ISOLATION_SERIALIZABLE:序列化,代价最高最可靠的隔离级别,该隔离级别能防止脏读、不可重复读、幻读。

五十五、Spring通知有哪些类型?

在AOP术语中,切面的工作被称为通知,实际上是程序执行时要通过SpringAOP框架触发的代码段。

Spring切面可以应用5种类型的通知:

1、前置通知(Before):在目标方法被调用之前调用通知功能;

2、后置通知(After):在目标方法完成之后调用通知,此时不会关心方法的输出是什么;

3、返回通知(After-returning ):在目标方法成功执行之后调用通知;

4、异常通知(After-throwing):在目标方法抛出异常后调用通知;

5、环绕通知(Around):通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为。

五十六、使用Spring框架的优点有哪些?

1、非侵入式设计

Spring是一种非侵入式(non-invasive)框架,它可以使应用程序代码对框架的依赖最小化。

2、 方便解耦、简化开发

Spring就是一个大工厂,可以将所有对象的创建和依赖关系的维护工作都交给Spring容器管理,大大地降低了组件之间的耦合性。

3、支持AOP(切面)

Spring提供了对AOP的支持,它允许将一些通用任务,如安全、事务、日志等进行集中式处理,从而提高了程序的复用性。

4、支持声明式事务处理

只需要通过配置就可以完成对事务的管理,而无需手动编程。

5、方便程序的测试

Spring提供了对Junit4的支持,可以通过注解方便的测试Spring程序。

6、方便集成各种优秀框架

Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持。

7、降低Java EE API的使用难度

Spring对Java EE开发中非常难用的一些API(如:JDBC、JavaMail等),都提供了封装,使这些API应用难度大大降低。

五十七、动态代理分哪些

1、JDK动态代理,利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理;

2、CGLIB动态代理,利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

五十八、Spring-AOP 的四种增强方式(前置增强、后置增强、异常增强、环绕增强)

1.前置增强,在核心功能之前执行的额外功能

2.后置增强,在核心功能之后执行的额外功能

3.异常增强,在核心功能发生异常时执行的额外功能

4.环绕增强,在核心功能之前以及之后执行的额外功能

五十九、什么是死锁

死锁(Deadlock):是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。称此时系统处于死锁状态或系统产生了死锁。称这些永远在互相等待的进程为死锁进程。

六十、死锁产生的四个必要条件

1、互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用

2、不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。

3、请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。

4、循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。

六十一、解决死锁的基本方法

1. 避免死锁

避免死锁是最好的解决方案,它通过对资源的请求进行限制,使得死锁不可能发生。Java中提供了一个专门的接口类java.util.concurrent.locks.Lock,可以使用它来避免死锁。

2. 可以打破循环等待条件

循环等待是死锁的核心之一。可以通过打破这个条件来解决死锁问题。Java中提供了一个工具类java.util.concurrent.locks.ReentrantLock,通过使用该类的tryLock()方法可以尝试获取锁资源,并在获取失败后立即释放已经获取的锁资源。

3. 使用超时等待机制

使用超时等待机制可以避免线程因为无法获取资源而一直等待的情况。Java中提供了一个接口类java.util.concurrent.locks.Condition,可以使用它来实现等待超时机制。

4. 按照顺序获取锁

按照顺序获取锁可以避免循环等待条件的发生。可以通过对资源的顺序进行管理,在获取锁资源时按照固定的顺序获取,从而避免死锁。

总结

解决死锁最好的方法是通过分析和设计,确保在程序运行时不会出现死锁的情况。其中,最简单的方法就是在设计时尽量减少锁的数量,避免出现循环等待等情况。

六十二、线程安全问题

什么是线程安全

是指计算机程序代码中的概念,当多个线程同时访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那就称这个对象时线程安全的。

什么是线程不安全

线程不安全是指在多线程并发执行某个代码时,由于缺乏适当的同步和协调机制,导致出现了逻辑上的错误,使得实际运行结果与预期不符。

六十三、throw和throws的区别

一、语法位置不同。throw用于函数内部,后面跟的是异常对象,而throws用于函数结

尾,后面跟的是异常类,后面可以跟多个不同的异常类,表示抛出不同的异常

二、关键字功能不同。throw用于抛出异常,并将问题立即抛出给上一级的调用者,

并且当throw执行到时,后面的其他语句不会执行。而throws只是用于声明异常,让调用者知道这里可能会出现问题,并提前处理异常发生情况,属于一种提前通知。

六十四、java异常

1. NullPointerException:空指针异常;

2. SQLException:数据库相关的异常;

3. IndexOutOfBoundsException:数组下标越界异常;

4. FileNotFoundException:打开文件失败时抛出;

5. IOException:当发生某种IO异常时抛出;

6. ClassCastException:当试图将对象强制转换为不是实例的子类时,抛出此异常;

7. NoSuchMethodException:无法找到某一方法时,抛出;

8. ArrayStoreException:试图将错误类型的对象存储到一个对象数组时抛出的异常;

9. NumberFormatException:当试图将字符串转换成数字时,失败了,抛出;

10. IllegalArgumentException抛出的异常表明向方法传递了一个不合法或不正确的参数;

11. ArithmeticException 当出现异常的运算条件时,抛出此异常。例如,一个整数“除以零”时,抛出此类的一个实例。

六十五、Service的作用

1、提供业务逻辑的封装和处理:Service层负责处理业务逻辑,将数据访问层获取到的数据进行处理,并根据业务需求进行逻辑判断和操作。它封装了具体的业务逻辑,使得表示层可以直接调用Service层提供的方法,而不需要关心具体的实现细节。

2、实现事务管理:Service层可以管理事务的开启、提交和回滚。在一个业务操作中,可能会涉及多个数据操作,为了保持数据的一致性和完整性,需要将这些操作放在一个事务中进行管理。Service层可以通过注解或编程方式管理事务,保证这些操作要么全部成功执行,要么全部回滚,达到数据的一致性。

3、提供对外接口:Service层可以将业务逻辑封装成对外的接口,供其他模块或系统进行调用。这样,不同的表示层(如Web、移动端等)可以通过调用Service层的接口来实现相同的业务逻辑,提高了代码的复用性和可维护性。

4、数据转换和封装:Service层可以对数据进行转换和封装,使得表示层能够更加方便地使用。例如,Service层可以将数据从数据库查询出来的原始形式转换成实体对象,或者将实体对象转换成DTO(Data Transfer Object)对象,方便表示层进行展示和传输。

总结,Service层在Java中具有负责业务逻辑的封装和处理、事务管理、提供对外接口以及数据转换和封装等作用,是连接表示层和数据访问层的重要一环。它能够有效地将应用程序的不同模块分离,提高代码的重用性、可维护性和可测试性。

六十六、List,Map,Set的了解

0

List简介

List继承于Collection接口,元素有序。List中允许有重复的元素,实现List接口的常用类有 LinkedList、ArrayList、Vector等。List是一个有序的集合,可以有重复的元素、查找元素效率高,插入删除效率低,因为删除时会引起其他元素的位置改变。

Set简介

Set也实现自Collection接口,元素无序,实现Set接口的常用类HashSet、TreeSet和LinkedHashSet 。Set中的值不能重复,不允许存储重复的元素(根据重写hashCode()和equals()方法来判断是不是同一对象)、没有索引,没有带索引的方法,所以也就不能使用普通的for循环进行遍历。

Map简介

Map集合是一个key-value(键值对)结构的双列集合,key不允许重复,value可以重复。

1、Map集合与Collection集合没有任何关系,这是与Collection集合同级的第二大集合操作接口;

2、Map是键值对结构的集合,以key-value结构进行保存(成对出现),其中key是唯一的

3、使用Collection集合不容易存取数据,但使用键值对的方式实现存取就比较简单。

六十七、HashMap和HashTable的区别?

1、两者父类不同

2、对外提供的接口不同:HashTable比HashMap多提供了elments()和contains()两个方法

3、对null的支持不同 HashTable kye和value都不能为null,HashMap中key可以有一个为null 但是只能存在一个

4、安全性不同、HashMap线程是不安全的但是效率高 HashTable 线程是安全的,因为他的方法上都有synchronized关键字。

5、初始容量大小和扩充容量大小不同

6、计算hash值的方法不同

六十八 、List,Map,Set能不能继承connection接口

list,set都继承了connection接口,而map没有继承

六十九、ArrayList和LinkedList的区别?

ArrayList底层是数组,增删慢,查找快。LinkedList底层是双向链表,增删快,查找慢。

1.ArrayList基于数组,需要连续内存,ArrayList基于双向链表,不需要连续内存

2. ArrayList随机访问快(可以根据下标访问),LinkedList随机访问慢(需要迭代遍历)

3.ArrayList尾部插入和删除性能可以,其他的头部中间插入删除慢,LinkedList头尾插入删除性能高,中间插入删除性能慢,

4.ArrayList可以CPU缓存,利用局部性原理。LinkedList占内存很多

对比区别

ArrayList

LinkedList

底层区别

底层是数组,增删慢,查找快

底层是双向链表,增删快,查找慢。

连续内存

基于数组,需要连续内存

基于双向链表,不需要连续内存

增删改查方面

尾部插入和删除性能可以,其他的头部中间插入删除慢

头尾插入删除性能高,中间插入删除性能慢

内存方面

可以CPU缓存,利用局部性原理

占内存很多

七十、数组和链表的区别?

链表

数组

内存占用

不需要连续的内存空间

需要连续的内存空间

大小可变

链表的大小可动态变化

数组大小固定,不能动态扩展

增删

较快,只需要修改前⼀个元素的指针即可

较慢,需要移动修改元素只有的所 有元素

查询

较慢,只能遍历查找

较快,可以通过下标直接访问

在访问方式上

必须是顺序访问,不能随机访问

可以随机访问其中的元素

空间的使用上

可以随意扩⼤

不可以扩大

七十一、单向链表和双向链表的区别

单向链表

双向链表

每个元素只有一个指针指向下一个元素的地址

每个元素只两一个指针指向上一个和下一个元素的地址

查询

较慢

较快,可以通过二分查找来提速

增删

较快

更快

存储

略高,除了存储元素,只会存储一个指针

较低,除了存储元素,需要存储两个指针

总结:双向链表的增、删、查优于单向链表,但是目前市面上用的较多的仍是单向链表,主要双向链表多一个指针,在存储效率上低于单向链表。一个指针在32位系统需要4个字节来存储,在64位系统需要8个字节来存储

扩容机制的了解

七十二、扩容机制的基本概念

扩容机制是指通过增加系统的资源,如计算能力、存储容量或网络带宽,来提高系统的性能和可扩展性。在扩容过程中,需要考虑系统的负载均衡、数据一致性和容错能力等问题。

七十三、扩容机制的原则

1.可伸缩性:扩容机制应能够根据需要动态地增加或减少系统资源,以适应不断变化的需求。

2. 透明性:在扩容过程中,系统的整体表现应该保持一致,对用户来说应该是透明的,不会影响用户的体验。

3. 容错能力:扩容机制应能够在某一资源故障时自动将负载转移至其他可用资源,并确保数据的完整性和一致性。

4. 成本效益:在选择扩容方案时,应综合考虑成本和性能的平衡,选择最经济合理的方案。

七十四、扩容的方式

1、垂直扩容

垂直扩容是指通过增加单个节点的计算资源来提升系统的性能。这包括增加服

务器的CPU、内存或存储容量等。垂直扩容通常适用于单机系统或负载较小的系

统,由于单节点的资源有限,对于高负载的系统可能会达到扩容的上限。

2、水平扩容

水平扩容是指通过增加节点数量来提高系统的性能和容量。这可以通过增加服

务器、虚拟机或容器等来实现。水平扩容可以提供更高的负载均衡和容错能力,但

涉及到数据一致性和通信开销等问题。

3、弹性伸缩

弹性伸缩是一种根据实时负载情况自动调整系统容量的扩容方法。它可以根据

负载的波动自动增加或减少节点数量,以实现资源的最优利用。弹性伸缩可以通过

自动化工具和监控系统来实现,具有很高的灵活性和自动化程度

4、数据分片

数据分片是一种将数据分布到多个节点上的扩容方法。每个节点负责处理一部

分数据,从而提高系统的整体处理能力。数据分片可以根据数据的特性和访问模式

进行不同的划分策略,如按照数据的关键字、哈希值或范围等进行划分。

总结

扩容机制是现代大数据处理和云计算应用中的重要组成部分。通过适当的扩容

方案,可以提高系统的性能、容量和可靠性。在选择扩容方案时,应综合考虑系统

的需求、资源和成本等因素,在具体情况下选择合适的扩容方法。通过合理的扩容

机制,可以帮助企业和组织应对快速变化的业务需求,提高系统的竞争力和可持续

发展能力

七十五、什么是Vue的生命周期 ?

Vue 的实例从创建到销毁的过程 ,就是生命周期 ,也就是从开始创建 ,初始化数据 ,编译模板 ,挂载Dom到渲染DOM ,更新数据再到渲染 ,卸载等一系列的过程 ,我们称这是Vue的生命周期

七十六、String、StringBuffer、StringBuilder的区别

0

1、String类型的字符串对象是不可变的,一旦String对象创建后,包含在这个对象中的字符系列是不可以改变的,直到这个对象被销毁。

2、StringBuilder和StringBuffer类型的字符串是可变的,不同的是StringBuffer类型的是线程安全的,对方法加了同步锁、而StringBuilder没加,不是线程安全的

3、如果是多线程环境下涉及到共享变量的插入和删除操作,StringBuffer则是首选。如果是非多线程操作并且有大量的字符串拼接,插入,删除操作则StringBuilder是首选。

七十七、重写和重载的区别是什么

1、定义不同:重载是定义相同的方法名、参数不同,重写是子类重写父类的方法

2、范围不同:重载是在一个类中,重写是子类与父类之间的

3、多态不同:重载是编译时的多态性,重写是运行时的多态性

4、参数不同:重载的参数个数、参数类型、参数的顺序可以不同,重写父类子方法参数必须相同

5、修饰不同:重载对修饰范围没有要求,重写要求重写方法的修饰范围大于或等于被重写方法的修饰范围

七十八、Java语言有哪些特点?

1. 简单性:Java语言设计简洁,易于学习和使用。它避免了一些复杂的语法和功能,并提供了清晰的语法规则和面向对象的编程模型。

2. 面向对象:Java是一种面向对象的编程语言,支持封装、继承和多态等面向对象的概念。这使得Java编程更加模块化、可重用和易于维护。

3. 平台无关性:Java语言以"一次编写,到处运行"的理念而闻名。它通过Java虚拟机(JVM)实现了平台无关性,使得Java程序可以在不同的操作系统上运行,只需在目标平台上安装适当的JVM。

4. 可移植性:由于Java的平台无关性,Java程序可以轻松地在不同的计算机和设备上移植和运行,而无需对源代码进行任何修改。

5. 安全性:Java提供了多种安全性特性,包括沙箱安全模型和内置的安全性机制。这使得Java程序能够在受限的环境中运行,防止恶意代码的执行,确保程序的安全性。

6. 多线程支持:Java具有内置的多线程支持,可以方便地创建和管理多线程应用程序。多线程使得程序可以同时执行多个任务,提高了程序的性能和效率。

7. 高性能:尽管Java是解释执行的,但借助即时编译器(Just-In-Time Compiler,JIT)的优化,Java程序可以实现接近原生代码的性能。

8. 大量的开发工具和库支持:Java拥有丰富的开发工具和开源库,为开发人员提供了广泛的选择和支持,使得开发Java应用程序更加高效和便捷。

七十九、面向对象编程的三大核心特性

(一)封装

封装的定义

何为封装?把事物抽象成一个类,将事物拥有的属性和动作隐藏起来,只保留特定的方法与外界联系。当内部的逻辑发生变化时,外部调用不用因此而修改,它们只调用开放的接口,而不用去关心内部的实现。

封装的好处

1、实现了专业的分工,将处理逻辑封装成一个方法,做到见名知其义

2、良好的封装能够减少耦合

3、隐藏信息,实现细节

(二)继承

继承的概念

继承是面向对象的最显著的一个特征。继承是从已有的类(父类或者超类)中派生出新的类(子类),新的类能吸收已有类的数据属性和行为,并能扩展新的能力(方法的覆盖/重写)。JAVA不支持多继承,一个类只能有一个父类。父类是子类的一般化,子类是父类的特殊化(具体化)

子类的特点

子类拥有父类非private的属性和方法

子类可以添加自己的方法和属性,即对父类进行扩展

子类可以重新定义父类的方法,即方法的覆盖/重写

构造函数

构造函数不能被继承,子类可以通过super()显示调用父类的构造函数

创建子类时,编译器会自动调用父类的无参构造函数

如果父类没有定义无参构造函数,子类必须在构造函数的第一行代码使用super()显示调用

(三)多态

多态的概念

多态的本质是:一个程序中同名的不同方法。在面向对象的程序设计中,多态主要有以下三种方式来实现。

1、通过子类对父类方法的覆盖来实现多态

2、通过一个类中方法的重载来实现多态

3、通过将子类的对象作为父类的对象实现多态。

八十、关于多态的向上转型和向下转型?

向上转型

子类对象转为父类,父类可以是接口。公式:Father f = new Son(); Father是父类或接口,Son是子类。

向下转型

父类对象转为子类。公式:Son s = (Son) f;

总结:在向上转型的时候我们可以直接转,但是在向下转型的时候我们必须强制类型转换。并且该父类必须实际指向了一个子类对象才可强制类型向下转型。

八十一、接口可以继承接口吗?接口、抽象类、实体类的关系

1、接口可以继承接口,抽象类不可以继承接口,但可以实现接口。

2、抽象类可以继承实体类。抽象类可以实现(implements)接口,抽象类是否可继承实体类,取决于实体类必须是否有明确的构造函数。

3、抽象类可以继承实体类,这是因为抽象类可继承性且有方法。

4、一个接口可以继承多个接口. interface C extends A, B {}是可以的;

5、 一个类可以实现多个接口: class D implements A,B,C{},但是一个类只能继承一个类,不能继承多个类 class B extends A{}

在继承类的同时,也可以实现多个接口: class E extends D implements A,B,C{} 这也正是选择用接口而不是抽象类的原因。

八十二、Static的了解

1、static是静态的意思,是一个修饰符,就像是一个形容词,是用来形容类,变量,方法的。

2、static修饰变量,这个变量就变成了静态变量,修饰方法这个方法就成了静态方法,

3、static关键字方便在没有创建对象的情况下来进行调用(方法/变量。

作用

1、静态变量:静态变量(有时也称为类变量)属于类本身,而不是类的任何特定实例。这意味着无论创建了多少个对象,都只有一个静态变量的副本。所有的对象都共享这个变量

0

2、静态方法:静态方法属于类本身,而不是类的任何特定实例。因此,你可以不创建类的对象而直接通过类名调用静态方法。

0

3、静态块:静态块在类加载时只执行一次。它通常用于初始化静态变量。静态代码块是不需要依赖main方法就可以独立运行的

0

4、常量:你可以使用static和final关键字来定义一个常量。这种常量在整个程序中只有一个实例,并且其值在初始化后不能再被修改

0

5、静态导入:在Java 5之后,你可以使用import static语句来导入一个类的所有静态成员,这样你就可以直接使用它们,而不需要每次都写出类名

0

八十三,高并发的解决方法主要有以下几种:

  1. 增加系统资源:可以通过增加服务器数量、CPU、内存、带宽等硬件资源,来提升系统的处理能力,从而应对高并发请求。这种解决方案可以通过集群负载均衡等技术来实现。

2.优化算法和代码:可以对系统的算法和代码进行优化,提升系统的执行效率,从而减少系统的响应时间和资源消耗,提高系统的并发能力。

3.缓存机制:可以通过缓存机制来减少系统的数据库和文件系统等IO操作,从而提升系统的响应速度和并发能力。常见的缓存技术包括内存存、分布式缓存等。

4.异步处理:可以通过异步处理来提升系统的并发能力,减少等待时间。常见的异步处理技术包括消息队列、线程池、协程等。

5.数据库优化:可以通过优化数据库结构、索引、SQL语句等方式,提升数据库的性能和并发能力,减少数据库的响应时间和负载压力。

6.CDN加速:可以通过使用CDN加速服务,将静态资源分布到全球多个节点上,提高访问速度和并发能力,减少服务器负载压力。

7集群处理:如果应用的性能已经很难提升了,还是存在并发问题,可以采用集群来处理,一台服务器搞不定,那就多来几台。

数据库方面知识点

一、MySQL

优点:体积小、速度快、总体拥有成本低,开源;

支持多种操作系统;

是开源数据库,提供的接口支持多种语言连接操作 ;

MySQL的核心程序采用完全的多线程编程。线程是轻量级的进程,它可以灵活地为用户提供服务,而不过多的系统资源。用多线程和C语言实现的mysql能很容易充分利用CPU;

MySql有一个非常灵活而且安全的权限和口令系统。当客户与MySql服务器连接时,他们之间所有的口令传送被加密,而且MySql支持主机认证;

支持ODBC for Windows, 支持所有的ODBC 2.5函数和其他许多函数, 可以用Access连接MySql服务器, 使得应用被扩展;

支持大型的数据库, 可以方便地支持上千万条记录的数据库。作为一个开放源代码的数据库,可以针对不同的应用进行相应的修改;

拥有一个非常快速而且稳定的基于线程的内存分配系统,可以持续使用面不必担心其稳定性;

MySQL同时提供高度多样性,能够提供很多不同的使用者介面,包括命令行客户端操作,网页浏览器,以及各式各样的程序语言介面,例如C+,Perl,Java,PHP,以及Python。你可以使用事先包装好的客户端,或者干脆自己写一个合适的应用程序。MySQL可用于Unix,Windows,以及OS/2等平台,因此它可以用在个人电脑或者是服务器上。

缺点:

不支持热备份;

MySQL最大的缺点是其安全系统,主要是复杂而非标准,另外只有到调用mysqladmin来重读用户权限时才发生改变;

没有一种存储过程(Stored Procedure)语言,这是对习惯于企业级数据库的程序员的最大限制;

MySQL的价格随平台和安装方式变化。Linux的MySQL如果由用户自己或系统管理员而不是第三方安装则是免费的,第三方案则必须付许可费。Unix或linux 自行安装 免费 、Unix或Linux 第三方安装 收费。

二、SQL Server

优点:

易用性、适合分布式组织的可伸缩性、用于决策支持的数据仓库功能、与许多其他服务器软件紧密关联的集成性、良好的性价比等;

为数据管理与分析带来了灵活性,允许单位在快速变化的环境中从容响应,从而获得竞争优势。从数据管理和分析角度看,将原始数据转化为商业智能和充分利用Web带来的机会非常重要。作为一个完备的数据库和数据分析包,SQLServer为快速开发新一代企业级商业应用程序、为企业赢得核心竞争优势打开了胜利之门。作为重要的基准测试可伸缩性和速度奖的记录保持者,SQLServer是一个具备完全Web支持的数据库产品,提供了对可扩展标记语言 (XML)的核心支持以及在Internet上和防火墙外进行查询的能力;

缺点:

开放性 :SQL Server 只能windows上运行没有丝毫开放性操作系统系统稳定对数据库十分重要Windows9X系列产品偏重于桌面应用NT server只适合小型企业而且windows平台靠性安全性和伸缩性非常有限象unix样久经考验尤其处理大数据库。

伸缩性并行性 :SQL server 并行实施和共存模型并成熟难处理日益增多用户数和数据卷伸缩性有限。

安全性:没有获得任何安全证书。

性能 :SQL Server 多用户时性能佳 。

客户端支持及应用模式: 客户端支持及应用模式。只支持C/S模式,SQL Server C/S结构只支持windows客户用ADO、DAO、OLEDB、ODBC连接。

使用风险:SQL server 完全重写代码经历了长期测试断延迟许多功能需要时间来证明并十分兼容。

三、Oracle

优点:

开放性:Oracle 能所有主流平台上运行(包括 windows)完全支持所有工业标准采用完全开放策略使客户选择适合解决方案对开发商全力支持。

可伸缩性,并行性:oracle 并行服务器通过使组结点共享同簇工作来扩展windownt能力提供高用性和高伸缩性簇解决方案windowsNT能满足需要用户把数据库移UNIXOracle并行服务器对各种UNIX平台集群机制都有着相当高集成度。

安全性:获得最高认证级别的ISO标准认证。

性能:Oracle 性能高 保持开放平台下TPC-D和TPC-C世界记录。

客户端支持及应用模式:Oracle 多层次网络计算支持多种工业标准用ODBC、JDBC、OCI等网络客户连接 。

使用风险:Oracle 长时间开发经验完全向下兼容得广泛应用地风险低。

缺点:

对硬件的要求很高;

价格比较昂贵;

管理维护麻烦一些;

操作比较复杂,需要技术含量较高。

四、数据库事务的主要作用

1、数据同步:事务使多个数据库或应用程序之间的修改可以被记录和跟踪。当一个数据库或应用程序执行修改时,其他数据库或应用程序可以检查修改是否已被提交,并确保修改正在被接收。

2、数据完整性:事务使多个数据库或应用程序之间的修改可以被验证,确保它们具有相同的数据完整性。如果修改不一致,数据库或应用程序可以执行相应的操作,例如撤销修改或拒绝事务。

3、并发控制:事务可以允许同时进行多个操作,这可以防止由于单个操作的失败而导致数据损坏或数据混乱。

4、恢复:事务可以使数据库或应用程序在发生故障时快速恢复到相同的状态。如果发生故障,事务可以将数据复制到其他数据库或应用程序,以确保数据的一致性。

5、性能优化:事务可以通过减少数据库的事务提交次数和增加数据库之间的复制次数来提高数据库性能。这可以通过在事务提交之前进行数据预填充或将数据复制到多个数据库来实现。

五、ACID

ACID,指数据库事务正确执行的四个基本要素的缩写。包含:

1、原子性(Atomicity)原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生,执行事务的过程中只要发生错误就回滚到原来的状态。

2、一致性(Consistency)事务前后数据的完整性必须保持一致,完整性约束不被破坏!

3、隔离性(Isolation)事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。

4、持久性(Durability)持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。

六、三大数据库的分页方式

MySQL-分页查询

使用limit语句放在查询语句的最后

公式:

要显示的页数 page,每页的条目数size select 查询列表 from 表 limit (page-1)*size,size;

案例1:查询前五条员工信息

SELECT * FROM employees LIMIT 0,5; SELECT * FROM employees LIMIT 5;

案例2:查询第11条——第25条(一共15条数据)

SELECT * FROM employees LIMIT 10,15;

代码讲解:则从10开始,往后的15条数据

案例3:有奖金的员工信息,并且工资较高的前10名显示出来

SELECT * FROM employees WHERE commission_pct IS NOT NULL ORDER BY salary DESC LIMIT 10 ;

Oracle实现分页查询

使用ROWNUM函数实现分页查询,ROWNUM是一个伪列,用于记录返回结果集中每一行的行号。ROWNUM是在查询结果返回之后计算的,因此它并不是存储在表中的实际列。

命令格式:

SELECT * FROM ( SELECT t.*, ROWNUM rn FROM table_name t WHERE ROWNUM <= 结束行) WHERE rn > 起始行

查询emp表前五行

select * from emp where rownum <=5;

查询表student中第6行到第10行的数据

SELECT * FROM ( SELECT t.*, ROWNUM rn FROM student t WHERE ROWNUM <= 10 ) WHERE rn > 5;

查询工资最高的前5人

select * from ( select ename from emp order by sal desc) where rownum<=5;

查询工资最高的6-10名

select ename from (select rownum a,e.* from(select ename from emp order by sal desc) e) where a between 6 and 10;

SQL Server实现分页查询

七、什么是索引?

索引是一种用于快速查询和检索数据的数据结构。常见的索引结构有: B 树, B+树和 Hash。

索引的作用就相当于目录的作用。打个比方: 我们在查字典的时候,如果没有目录,那我们就只能一页一页的去找我们需要查的那个字,速度很慢。如果有目录了,我们只需要先去目录里查找字的位置,然后直接翻到那一页就行了。

索引的优点

  可以大大加快 数据的检索速度(大大减少的检索的数据量), 这也是创建索引的最主要的原因。毕竟大部分系统的读请求总是大于写请求的。 另外,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。

索引的缺点:

  1. 创建索引和维护索引需要耗费许多时间:当对表中的数据进行增删改的时候,如果数据有索引,那么索引也需要动态的修改,会降低 SQL 执行效率。
  2. 占用物理存储空间 :索引需要使用物理文件存储,也会耗费一定空间。

八、索引的分类

索引可以按照不同的角度进行分类:

  1. 从功能逻辑上说,索引主要有普通索引、唯一索引、主键索引、全文索引。
  2. 按照物理实现方式,索引可以分为聚簇索引和非聚簇索引。
  3. 按照作用字段个数进行划分,索引可以分为单列索引和联合索引。
  4. 从数据结构角度分类,索引包括B+tree索引、Hash索引、Full-text索引。
  5. 按照物理存储分类,索引可以分为聚簇索引和二级索引。
  6. 从索引的逻辑设计角度分类,索引可以是单列索引、多列索引、唯一索引、非唯一索引和基于函数的索引。
  7. 从物理实现角度分类,索引可以是分区或非分区索引、B-树等。

九、什么是主键索引?

主键索引是⼀种特殊的唯⼀索引,⼀个表只能有⼀个主键且不允许有空值;索引列只能出现⼀次且必须唯⼀。

十、什么情况下表需要建立索引

1、数据量较大的表:数据量较大的表查询效率较低,需要创建索引来提高查询速度。

2、经常被查询的表:经常被查询的表需要创建索引来加速查询操作。

3、进行连接操作的表:进行连接操作的表需要创建索引来提高连接效率。

十一、创建索引的规则

 1. 只给频繁查询的列创建索引,这样可以提高查询效率,而不会影响到其他的操作。 

 2. 不要给超大型数据类型(如BLOB和TEXT)创建索引,因为它们会导致索引文件变得非常大,影响性能。

 3. 对于有唯一性约束的列,一定要创建唯一性索引,这样可以保证数据的完整性。

 4. 避免创建过多的索引,因为过多的索引会占用大量的磁盘空间,同时也会影响数据的更新和插入操作。

 5. 如果需要对多个列进行查询,可以考虑创建复合索引,这样可以提高查询效率。

 6. 对于需要排序或者分组的列,可以创建聚簇索引,这样可以避免进行全表扫描,提高查询效率。

 7. 定期对索引进行维护和优化,包括删除不必要的索引、重新构建索引和检查索引的碎片等操作,以保证索引的高效性。

十二、什么情况下要避免使用索引?

1.数据表非常小:如果数据表的大小非常小,可能没有必要使用索引。在数据表中进行全表扫描可能比使用索引更快。因此,在这种情况下使用索引可能会引入额外的开销,并且不会带来任何明显的性能优势。

2.数据表的修改频率非常高:当数据表的修改频率非常高时,比如说有大量的插入、更新和删除操作,使用索引可能会导致数据不稳定。索引需要在每次数据修改时进行更新,这可能导致额外的开销和性能下降。在这种情况下,可以考虑在关键查询上使用索引,而在频繁修改的列上避免使用索引。

3.数据表的查询频率非常低:有些数据表很少被查询,或者只被查询一次。在这种情况下,索引可能不会带来任何明显的性能优势。因为索引需要占用额外的存储空间,并且需要在查询时进行额外的计算,如果数据表很少被查询,使用索引可能会浪费资源。

4.查询中使用的列不适合索引:并非所有的列都适合创建索引。有些列的取值范围较小,重复的值较多,这种情况下使用索引可能不会提高查询性能。例如,性别列通常只有两个可能的取值,男和女,在这种情况下使用索引可能不会有明显的性能优势。

5.数据表的连接太多:当需要连接多个数据表进行查询时,如果每个表都有多个索引,可能会导致查询性能下降。连接操作通常需要额外的计算和内存消耗,如果每个表都有多个索引,这些消耗可能会明显增加。

十三、如何避免全表查询

1. 创建合适的索引:在创建索引时,需要根据实际情况选择合适的字段作为索引,避免创建无用的索引,同时也要避免创建过多的索引,因为过多的索引会影响数据库的性能。

2. 使用覆盖索引:覆盖索引是指查询语句中所需要的字段都在索引中,不需要再去查询表中的数据,这样可以避免全表扫描。

3. 分区表:将大表分成多个小表,每个小表都有自己的索引,这样可以避免全表扫描,提高查询效率。

4. 使用缓存技术:将经常查询的数据缓存到内存中,减少数据库的访问次数,提高系统性能。

5. 优化查询语句:尽量避免使用不必要的查询语句,如使用子查询、联合查询等复杂查询语句,优化查询条件,减少查询数据量。

十四、MYSQL端口号是?

1、MySQL默认的端口号是3306

  • 21
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值