Java面试题总结

Java语言

多线程

  • 什么是多线程:多线程指一个程序中包含多个线程,可以同时执行多个不同的任务。
  • 多线程优劣:优点是可以提高系统资源的利用率,提高程序效率。缺点是需要协调管理,需要进行同步。
  • 并发和并行的区别:并发是多个任务同时开启,在CPU的时间片轮转中交替执行;并行是多个任务在多核CPU上同时执行,真正意义上的同时运行。
  • 并发编程三要素:原子性,可见性和有序性。原子:一个任务要么全部执行,要么全部不执行;可见:一个线程对共享变量操作后,结果对其他线程可见;有序:程序的执行顺序按照代码先后顺序来执行。
  • 线程与进程区别:进程是操作系统资源分配的基本单位,线程是操作系统任务调度的基本单位。
  • 线程死锁:多个线程由于竞争资源而造成的循环等待的阻塞现象。
  • 形成死锁的条件:(1)互斥条件:一个资源每次只能被一个进程使用。(2)请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。(3)不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺。(4)循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
  • 如何解决死锁:一个进程无法申请到其他资源时,释放已经拥有的资源;按顺序申请资源;一次性申请所有资源。
  • 创建线程的四种方式:继承Thread类;实现Runnable接口;实现Callable接口;使用Executors创建线程池。
  • run和start方法的区别:run方法只是普通方法,start可以启动线程,让其进入就绪状态等待调度;
  • 线程生命周期:新建,就绪,阻塞,等待,销毁;
  • sleep和wait的区别:sleep不释放锁,wait释放锁;sleep是Thread类的静态方法,wait是Object类的方法。
  • 如何在两个线程之间共享数据:共享变量。
  • 什么是线程安全:在多线程的环境中,通过同步的方式让共享变量能够被正确处理,就是线程安全。
  • 什么是线程池:提前创建若干个线程保存在一起,等待处理任务,处理完毕后不销毁,继续等待下一个任务,就是线程池。使用Executors接口创建线程池。
  • 四种线程池的创建:newCachedTheadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor。
  • 线程池的优点:重用存在的线程,避免对象创建和销毁的开销;控制最大线程数,避免资源竞争造成的阻塞。
  • 乐观锁和悲观锁:乐观锁不对操作的数据加锁,只在提交数据的时候验证是否被修改过;悲观锁在操作数据的期间加锁,等锁释放后其他线程才能对数据进行访问修改。
  • 多线程同步有哪几种方法:synchronized关键字;手动上lock;分布式锁。
  • synchronized的底层实现原理:synchronized可以保证方法或者代码块在运行时,同一时刻只有一个方法可以进入到临界区,同时它还可以保证共享变量内存的可见性。

集合框架

  • 什么是集合:集合是一种容器,用来存放对象信息。
  • 数组和集合的区别:数组长度不可变,集合可动态扩容;数组元素可以是基本类型和对象,集合只能保存对象。
  • Collections和Collection的区别:Collections是工具类,提供一系列静态方法用于对集合元素进行排序、搜索和线程安全等各种操作。Collection是集合的顶级接口。
  • List、Set、Map区别:List有序,可重复,有索引;Set无序,不可重复;Map:键值对存储,无序,不可重复。
  • HashMap和Hashtable区别:HashMap线程不安全,效率高;Hashtable线程安全,效率低。
  • HashMap的数据结构:数组+链表+红黑树。
  • HashSet实现原理:底层由HashMap实现,HashSet的值存放于key上,value统一为PRESENT。
  • ArrayList和LinkList的区别:ArrayList底层是数组,LinkList底层是链表。
  • ArrayList和Vector的区别:Vector线程安全,ArrayList非线程安全。
  • 哪些集合是线程安全的:Vector,Hashtable,ConcurrentHashMap,Stack。

其他

  • 常见的Exception:NullPointException,SQLException,IOException,IndexOutOfBoundsException,FileNotFoundException。
  • String不是基本数据类型,而是一个类。
  • String和StringBuffer的区别:String是不可变对象,一旦被创建就不能修改它的值,对于已经存在的String对象,修改值的内部实现是重新创建一个新的对象。StringBuffer是可变的对象,修改时候不会重新创建对象。
  • Int和Integer的区别:int是基本数据类型,Integer是引用数据类型。int默认值是0,integer默认值是null。
  • 运行时异常和一般异常的区别:运行时异常都是RuntimeException类及其子类,一般异常都是Exception类及其子类;运行时异常在程序中可以捕获处理也可以不处理,一般异常必须捕获处理,否则不能编译通过。
  • JDK是开发环境,包含JRE;JRE是运行时环境,不包括JDK。
  • 自动装箱:基本数据类型转换为包装器类型;自动拆箱:包装器类型转换为基本数据类型。
  • final,finally,finalize的区别:final是修饰符,表明变量不可修改或类不可继承;finally是异常捕获后必然执行的语句块;finalize是方法名,用于在垃圾收集器将对象彻底清除前的清理工作。
  • Math.round()是四舍五入的意思。
  • i++是返回原来的值执行语句,再加一;++i是先返回+1后的值,再执行语句。
  • try finally问题:

    public class Demo {
      public static void main(String[] args) {
          Demo demo=new Demo();
          System.out.println(demo.test());
      }
    
      private int test(){
          try {
              System.out.println("try");
              return 0;
          }
          finally {
              System.out.println("finally");
          }
      }
    }

    最终执行结果是:

    try
    finally
    0

    也就是说,有return的话return最后执行,其他语句块按顺序执行。

  • 一个变量的定义的修饰符的顺序:private final static int i=1;

网络

  • TCP与UDP区别:TCP有连接,UDP无连接。TCP可靠传输,UDP不可靠传输。
  • 三次握手四次挥手:三次握手,客户端发送SYN数据包到服务器,服务器收到SYN后发送SYN+ACK数据包,客户端收到SYN+ACK再向服务器发送ACK完成三次握手,开始传输数据;四次挥手,主动发送到被动一个FIN,被动受到FIN发送ACK,被动发送FIN,主动收到FIN发送ACK。
  • 四层网络模型:应用层,传输层,网络层、链路层。
  • 什么是Socket:套接字,就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象,使用IP地址+传输协议+端口号的方式创建连接。
  • IO流:用于处理设备之间传输数据的流式管道。输入读取,输出写出。
  • BIO,NIO,AIO的区别:BIO是同步阻塞方式,NIO是同步非阻塞方式,AIO是异步非阻塞方式。
  • 网络层协议: IP协议,ICMP协议, ARP协议;传输层协议: TCP协议,UDP协议;应用层协议: FTP,SMTP,HTTP,DNS。
  • Session, Cookie, Token的区别:Session 和 Cookie 的主要目的就是为了弥补 HTTP 的无状态特性。Session存储在服务器端,用于保存一次会话的状态。Cookie存储在客户端,用于保存用户的数据。token是验证令牌,用于向服务器验证自己的用户身份。

Redis

  • 什么是Redis:开源的、可基于内存也可以持久化的基于键值对的高性能非关系型数据库。
  • 为什么要使用Redis:高性能和高并发,基于内存速度快,数据结构简单,天然比关系型数据库支持更高的并发量和性能。
  • Redis支持的数据类型:可以存储键和五种类型的值的映射。键仅支持字符串,值支持String、List、Set、HashMap、ZSet。
  • 优点:读写性能强,支持持久化,支持主从复制;缺点:数据库容量受到物理内存的限制。
  • 什么是Redis持久化,Redis有哪些持久化方式:持久化就是将内存中保存的数据落在磁盘上,防止因内存断电导致的丢失。方式:RDB,把当前数据生成快照保存。AOF,记录每次对数据的操作到硬盘。
  • 缓存异常:

    • 缓存雪崩:缓存同一时间大面积过期失效,导致后面的请求都落在数据库上,数据库承受大量请求崩掉。
    • 缓存穿透:请求缓存和数据库中都没有的数据,导致所有请求都落到数据库上。
    • 缓存击穿:缓存中没有但数据库中有的数据,由于并发用户多,同时读取缓存未读取到数据,同时去数据库读取数据,数据库压力过大。

nginx

  • 什么是nginx:是一种反向代理服务器。反向代理指可以代理外部网络访问内部网络。
  • nginx优点:内存小,高并发,相应快。
  • 处理请求的过程:首先由listen和server_name指令匹配server模块,再匹配server模块里的location,location就是实际地址。
  • 正向代理和反向代理:正向代理代理客户端,反向代理代理服务端。

Spring框架

  • 什么是Spring:轻量级的Java开发框架,为了解决企业级应用开发的业务逻辑层和其他层耦合的问题。
  • Spring框架的核心:IOC容器,面向切片和依赖注入。
  • 依赖注入:依赖类不由程序员实例化,而是通过Spring容器创建指定实例并且将实例注入到需要该对象的类中。
  • Spring框架中的设计模式:工厂模式(FactiryBean接口)和单例模式(Bean)。
  • Spring常用注解:

    • 声明bean的注解:Component,Service,Controller
    • 注入bean的注解:AutoWired byType,Resource byName。
    • 配置类:Configuration声明当前类是配置类,bean声明当前方法的返回值是一个bean,ComponentScan用于对组件进行扫描。
    • @value为属性注入值。
    • SpringMVC:RequestMapping用于映射Web请求,ResponseBody支持将返回值放在响应体内,RequestBody允许请求的参数放在请求体中用于获取值,RestController为Controller的响应值放在响应体内。
    • 事务注解:Transaction
  • Spring框架的好处:解耦合,轻量,方便管理和配置。
  • IOC容器的理解:Spring IOC容器负责创建和管理对象,简化应用开发。
  • 不同方式的自动装配:byName:通过属性名自动装配,Spring容器在配置文件中发现bean的autowire属性被设置成byname,之后容器试图匹配、装配和该属性具有相同名字的bean。byType:通过参数类型自动装配,Spring容器在配置文件中发现bean的autowire属性被设置成byType,之后容器试图匹配、装配和该bean的属性具有相同类型的bean。如果有多个bean符合条件,则抛出错误。
  • Spring Boot是什么:是精简了配置的Spring。

Javaweb

  • Servlet:运行在服务器上的一个程序,用来处理对服务器的请求。
  • JSP和Servlet:JSP用于页面展示,Servlet用于逻辑控制。Servlet是一个完整的Java类。
  • 数据库
  • 索引:索引是对数据库中一个或多个列进行排序的数据结构,帮助我们快速检索数据库中的数据。

MQ

  • 消息队列:是一种可以存储、传递消息的容器,常用于分布式系统中减轻服务器直接压力。
  • 好处:解耦、异步、削峰。
  • RPC:远程过程调用。

数据库

  • 索引:使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构。类似于书籍的目录。
  • HAVING 子句可以让我们筛选分组后的各组数据。WHERE 子句在所选列上设置条件,而 HAVING 子句则在由 GROUP BY 子句创建的分组上设置条件。
  • PostgreSQL 中的 limit 子句用于限制 SELECT 语句中查询的数据的数量。
  • DISTINCT 关键字与 SELECT 语句一起使用,用于去除重复记录,只获取唯一的记录。
  • 索引不应该使用在较小的表上。索引不应该使用在有频繁的大批量的更新或插入操作的表上。索引不应该使用在含有大量的 NULL 值的列上。索引不应该使用在频繁操作的列上。
  • 视图是一张假表,只不过是通过相关的名称存储在数据库中的一个 PostgreSQL 语句。
  • 触发器是数据库的回调函数,它会在指定的数据库事件发生时自动执行/调用。

简历相关的面试题

  • Linux怎么样让终端程序在后台执行?有两种方式。第一种是用Ctrl+Z让程序暂停,然后使用bg命令让程序在后台继续执行,这种方式在退出终端后程序就会结束执行;第二种是在命令后加&符号,让命令一开始启动就在后台运行。
  • docker run -it中的it是什么意思?-t让docker分配一个伪终端并绑定到容器的标准输入上, -i以交互模式运行容器,让容器的标准输入保持打开。这样一个需要交互的容器实例才不会在启动后立刻结束运行。
  • 什么是中台?前台的支撑系统,基础设施层之上的通用业务层,这些业务能满足公共需求,将这些中台中的业务模块组合之后可以灵活的提供多种前台需要的能力。
  • 中台解决了什么问题?中台解决了重复造轮子的问题,比如在多个项目中需要操作用户和订单,那么不需要多次对对应的模块进行开发,只需调用对应中台的接口即可。

杨坚强
2 声望2 粉丝

热爱技术