面试题(杂项)

1. 怎么实现动态代理?

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

2. 什么是反射?

反射是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为 Java 语言的反射机制。

3. 如何实现对象克隆?

  • 实现 Cloneable 接口并重写 Object 类中的 clone() 方法。
  • 实现 Serializable 接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。

4. 深拷贝和浅拷贝区别是什么?

  • 浅克隆:当对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有复制。
  • 深克隆:除了对象本身被复制外,对象所包含的所有成员变量也将复制。

5. JSP 有哪些内置对象?作用分别是什么?

JSP 有 9 大内置对象:

  • request:封装客户端的请求,其中包含来自 get 或 post 请求的参数;
  • response:封装服务器对客户端的响应;
  • pageContext:通过该对象可以获取其他对象;
  • session:封装用户会话的对象;
  • application:封装服务器运行环境的对象;
  • out:输出服务器响应的输出流对象;
  • config:Web 应用的配置对象;
  • page:JSP 页面本身(相当于 Java 程序中的 this);
  • exception:封装页面抛出异常的对象。

6. session 和 cookie 有什么区别?

  • 存储位置不同:session 存储在服务器端;cookie 存储在浏览器端。
  • 安全性不同:cookie 安全性一般,在浏览器存储,可以被伪造和修改。
  • 容量和个数限制:cookie 有容量限制,每个站点下的 cookie 也有个数限制。
  • 存储的多样性:session 可以存储在 Redis 中、数据库中、应用程序中;而 cookie 只能存储在浏览器中。

7. 如何避免 SQL 注入?

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

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

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

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

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

10. 如何实现跨域?

实现跨域有以下几种方案:

  • 服务器端运行跨域 设置 CORS 等于 *;
  • 在单个接口使用注解 @CrossOrigin 运行跨域;
  • 使用 jsonp 跨域;

11. 说一下你熟悉的设计模式?

  • 单例模式:保证被创建一次,节省系统开销。
  • 工厂模式(简单工厂、抽象工厂):解耦代码。
  • 观察者模式:定义了对象之间的一对多的依赖,这样一来,当一个对象改变时,它的所有的依赖者都会收到通知并自动更新。
  • 外观模式:提供一个统一的接口,用来访问子系统中的一群接口,外观定义了一个高层的接口,让子系统更容易使用。
  • 模版方法模式:定义了一个算法的骨架,而将一些步骤延迟到子类中,模版方法使得子类可以在不改变算法结构的情况下,重新定义算法的步骤。
  • 状态模式:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。

12. 简单工厂和抽象工厂有什么区别?

  • 简单工厂:用来生产同一等级结构中的任意产品,对于增加新的产品,无能为力。
  • 工厂方法:用来生产同一等级结构中的固定产品,支持增加任意产品。
  • 抽象工厂:用来生产不同产品族的全部产品,对于增加新的产品,无能为力;支持增加产品族。

13. spring boot 核心配置文件是什么?

spring boot 核心的两个配置文件:

  • bootstrap (. yml 或者 . properties):boostrap 由父 ApplicationContext 加载的,比 applicaton 优先加载,且 boostrap 里面的属性不能被覆盖;
  • application (. yml 或者 . properties):用于 spring boot 项目的自动化配置。

14 spring boot 配置文件有哪几种类型?它们有什么区别?

配置文件有 . properties 格式和 . yml 格式,它们主要的区别是书法风格不同。

. properties 配置如下:

spring. RabbitMQ. port=5672

. yml 配置如下:

spring:
    RabbitMQ:
        port: 5672

. yml 格式不支持 @PropertySource 注解导入。

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

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

16.说一下 MySQL 常用的引擎?

· InnoDB 引擎:mysql 5.1 后默认的数据库引擎,提供了对数据库 acid 事务的支持,并且还提供了行级锁和外键的约束,它的设计的目标就是处理大数据容量的数据库系统。MySQL 运行的时候,InnoDB 会在内存中建立缓冲池,用于缓冲数据和索引。但是该引擎是不支持全文搜索,同时启动也比较的慢,它是不会保存表的行数的,所以当进行 select count(*) from table 指令的时候,需要进行扫描全表。由于锁的粒度小,写操作是不会锁定全表的,所以在并发度较高的场景下使用会提升效率的。

· MyIASM 引擎:不提供事务的支持,也不支持行级锁和外键。因此当执行插入和更新语句时,即执行写操作的时候需要锁定这个表,所以会导致效率会降低。不过和 InnoDB 不同的是,MyIASM 引擎是保存了表的行数,于是当进行 select count(*) from table 语句时,可以直接的读取已经保存的值而不需要进行扫描全表。所以,如果表的读操作远远多于写操作时,并且不需要事务的支持的,可以将 MyIASM 作为数据库引擎的首选。

17. 说一下乐观锁和悲观锁?

  • 乐观锁:每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在提交更新的时候会判断一下在此期间别人有没有去更新这个数据。
  • 悲观锁:每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻止,直到这个锁被释放。

数据库的乐观锁需要自己实现,在表里面添加一个 version 字段,每次修改成功值加 1,这样每次修改的时候先对比一下,自己拥有的 version 和数据库现在的 version 是否一致,如果不一致就不修改,这样就实现了乐观锁。

18. 如何做 MySQL 的性能优化?

  • 为搜索字段创建索引。
  • 避免使用 select *,列出需要查询的字段。
  • 垂直分割分表。
  • 选择正确的存储引擎。

19.Servlet 生命周期

Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:

  • Servlet 初始化后调用 init () 方法。
  • Servlet 调用 service() 方法来处理客户端的请求。
  • Servlet 销毁前调用 destroy() 方法。
  • 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

20.事务的七种传播类型、及案例

REQUIRED(默认):支持使用当前事务,如果当前事务不存在,创建一个新事务。

SUPPORTS:支持使用当前事务,如果当前事务不存在,则不使用事务。

MANDATORY:中文翻译为强制,支持使用当前事务,如果当前事务不存在,则抛出Exception。
REQUIRES_NEW:创建一个新事务,如果当前事务存在,把当前事务挂起。
NOT_SUPPORTED:无事务执行,如果当前事务存在,把当前事务挂起。
NEVER:无事务执行,如果当前有事务则抛出Exception。
NESTED:嵌套事务,如果当前事务存在,那么在嵌套的事务中执行。如果当前事务不存在,则表现跟REQUIRED一样。

21.Count(*)和Count(字段)的区别

对于count(*)而言,只要有记录,就被纳入统计
对于count(字段),如果该字段的值为null,则不会纳入统计。

22.重载(Overload)和重写(Override)的区别。

方法的重载和重写都是实现多态的方式, 区别在于前者实现的是编译时的多态性, 而后者实现的是运行时的多态性。重载发生在一个类中, 同名的方法如果有不同的参数列表( 参数类型不同、参数个数不同或者二者都不同) 则视为重载; 重写发生在子类与父类之间, 重写要求子类被重写方法与父类被重写方法有相同的返回类型, 比父类被重写方法更好访问, 不能比父类被重写方法声明更多的异常( 里氏代换原则) 。

23.抽象方法特殊在哪里?和抽象类的关系?

抽象方法是一种特殊的方法:它只有声明,而没有具体的实现。

抽象方法必须用abstract关键字进行修饰。如果一个类含有抽象方法,则称这个类为抽象类,抽象类必须在类前用abstract关键字修饰。因为抽象类中含有无具体实现的方法,所以不能用抽象类创建对象。

抽象类里面不一定有抽象方法,但是有抽象方法一定是抽象类,属性和普通类属性一样

24.static 执行顺序

如果不继承别的类,那么执行顺序应该是:
static代码块–>普通代码块–>类构造方法
如果继承了别的类,那么执行顺序应该是:
父类static代码块–>子类static代码块–>父类普通代码块–>父类构造方法–>子类普通代码块–>子类构造方法

25.静态方法是否可以被重写

无法被重写的

26.阐述静态变量和实例变量的区别。

静态变量是被 static 修饰符修饰的变量, 也称为类变量, 它属于类, 不属于类的 任何一个对象, 一个类不管创建多少个对象, 静态变量在内存中有且仅有一个拷贝; 实例变量必须依存于某一实例, 需要先创建对象然后通过对象才能访问到它。静态变量可以实现让多个对象共享内存。

27.synchronized 关键字的用法?

synchronized 关键字可以将对象或者方法标记为同步, 以实现对对象和方法的互斥访问, 可以用 synchronized( 对象) { … }定义同步代码块, 或者在声明方法时将synchronized 作为方法的修饰符。

28.如何用 Java 代码列出一个目录下所有的文件?

import java.io.File;
import java.util.ArrayList;

/**
 * @作者 youzi
 * @创建时间 2021/10/22 0:14
 */
public class Test02 {
    private static ArrayList<String> filelist = new ArrayList<String>();

    public static void main(String[] args) throws Exception {

        String filePath = "F://";
        getFiles(filePath);
    }
    /*
     * 通过递归得到某一路径下所有的目录及其文件
     */
    static void getFiles(String filePath){
        File root = new File(filePath);
        File[] files = root.listFiles();
        for(File file:files){
            if(file.isDirectory()){
                /*
                 * 递归调用
                 */
                getFiles(file.getAbsolutePath());
                filelist.add(file.getAbsolutePath());
                System.out.println("显示"+filePath+"下所有子目录及其文件"+file.getAbsolutePath());
            }else{
                System.out.println("显示"+filePath+"下所有子目录"+file.getAbsolutePath());
            }
        }
    }
}

29.什么是“依赖注入”和“控制反转”?为什么有人使用?

控制反转( IOC) 是 Spring 框架的核心思想, 用我自己的话说, 就是你要做一件事, 别自己可劲 new 了, 你就说你要干啥, 然后外包出去就好~

依赖注入( DI) 在我浅薄的想法中, 就是通过接口的引用和构造方法的表达, 将一些事情整好了反过来传给需要用到的地方~

30.构造器注入和 setter 依赖注入,那种方式更好?

每种方式都有它的缺点和优点。构造器注入保证所有的注入都被初始化, 但是setter 注入提供更好的灵活性来设置可选依赖。如果使用 XML 来描述依赖,Setter 注入的可读写会更强。经验法则是强制依赖使用构造器注入, 可选依赖使用setter 注入。

31.Spring Bean 容器的生命周期是什么样的?

Spring Bean 容器的生命周期流程如下:

1、Spring 容器根据配置中的 bean 定义中实例化 bean。

2、Spring 使用依赖注入填充所有属性, 如 bean 中所定义的配置。

3、如果 bean 实现BeanNameAware 接口, 则工厂通过传递 bean 的 ID 来调用setBeanName()。

4 、如果 bean 实现 BeanFactoryAware 接口, 工厂通过传递自身的实例来调用 setBeanFactory()。

5、如果存在与 bean 关联的任何BeanPostProcessors , 则调用 preProcessBeforeInitialization() 方法。 6 、如果为 bean 指定了 init 方法( <bean> 的 init-method 属性) , 那么将调用它。

7 、最后, 如果存在与 bean 关联的任何 BeanPostProcessors, 则将调用 postProcessAfterInitialization() 方法。

8、如果 bean 实现DisposableBean 接口, 当 spring 容器关闭时, 会调用 destory() 。

9 、如果为bean 指定了 destroy 方法( <bean> 的 destroy-method 属性),那么将调用它。

32.JDBC五大操作步骤

第一步 注册驱动 class.forname(“com.mysql.jdbc.driver”)
第二步 连接数据库 connection c = DriverManager.getconnection(“jdbc:mqsql://localhost:3306/数据库Characterencoding=utf-8”,”root”,”123456”)
第三步 创建执行sql语句的statement statement s = c.creatstatement();
S.execute(SQL语句)
第四步 执行处理结果 resultset rs = s.excutequery(sql)
第五步 释放资源 resultset.close statement.close connection.close

33.简述 Mybatis 的插件运行原理,以及如何编写一个插件。

答: Mybatis 仅可以编写针对 ParameterHandler、ResultSetHandler、StatementHandler 、 Executor 这 4 种接口的插件, Mybatis 使用 JDK 的动态代理, 为需要拦截的接口生成代理对象以实现接口方法拦截功能, 每当执行这 4 种 接口对象的方法时,就会进入拦截方法,具体就是 InvocationHandler 的 invoke() 方法, 当然, 只会拦截那些你指定需要拦截的方法。

编写插件: 实现 Mybatis 的 Interceptor 接口并复写 intercept()方法, 然后在给插件编写注解, 指定要拦截哪一个接口的哪些方法即可, 记住, 别忘了在配置文 件中配置你编写的插件。

34.什么是ZooKeeper ?

ZooKeeper 是一个开放源码的分布式协调服务, 它是集群的管理者, 监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。最终, 将简单易用的接口和性能高效、功能稳定的系统提供给用户。

分布式应用程序可以基于 Zookeeper 实现诸如数据发布/ 订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。

35.Zookeeper 保证了如下分布式一致性特性:

1、顺序一致性

2、原子性

3、单一视图

4、可靠性

5、实时性( 最终一致性)

36. ZooKeeper 提供了什么?

1、文件系统

2、通知机制

37. zookeeper 负载均衡和nginx 负载均衡区别

zk 的负载均衡是可以调控, nginx 只是能调权重, 其他需要可控的都需要自己写插件; 但是 nginx 的吞吐量比 zk 大很多, 应该说按业务选择用哪种方式。

38、为什么 Redis 需要把所有数据放到内存中?

答:Redis 为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘。所以 redis 具有快速和数据持久化的特征。如果不将数据放在内存中,磁盘I/O 速度为严重影响 redis 的性能。在内存越来越便宜的今天, redis 将会越来越受欢迎。如果设置了最大使用的内存, 则数据已有记录数达到内存限值后不能继续插入新值。

39.MySQL索引失效

1.前%号

2.没有单引号

3.or

40.MyBatis和MyBatis-Plus的区别是什么?

  • Mybatis是一款优秀的持久层框架支持自定义SQL查询、存储过程和高级映射,消除了几乎所有的JDBC代码和参数的手动设置以及结果集的检索。MyBatis可以使用简单的XML或者注解进行映射和配置,通过将参数映射到配置的SQL最终解析为执行的SQL语句,查询后将SQl结果集映射成java对象返回。
  • MyBatis-plus是一款MyBatis的增强工具,在MyBatis 的基础上只做增强不做改变。其是国内团队苞米豆在MyBatis基础上开发的增强框架,扩展了一些功能,以提高效率。引入 Mybatis-Plus 不会对现有的 Mybatis 构架产生任何影响,而且 MyBatis-plus 支持所有 Mybatis 原生的特性

    • 依赖少:仅仅依赖 Mybatis 以及 Mybatis-Spring 。
    • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作 。
    • 预防Sql注入:内置 Sql 注入剥离器,有效预防Sql注入攻击 。
    • 通用CRUD操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求 。
    • 支持代码生成:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码(生成自定义文件,避免开发重复代码),支持模板引擎、有超多自定义配置等。

41.多线程

多线程是为了同步完成多项任务,不是为了提高运行效率,而是为了提高资源使用效率来提高系统的效率。线程是在同一时间需要完成多项任务的时候实现的。

评论

暂无

添加新评论