Java后端面试题汇总(部分解析)

Java后端面试题汇总

这里写自定义目录标题

Java

Java基础

  1. short s1 = 1; s1 = s1 + 1;有错吗? short s1 = 1; s1 += 1; 有错吗?

  2. Object 类常用方法有那些?

  3. java 中是值传递引用传递?

    值传递。对象类型传的是引用对象内存地址的值,也是值传递,但是可以直接修改对象。

  4. 构造方法能不能重写?能不能重载?

    可以重载,但是不能被重写,因为构造方法是不能被继承的。

  5. 抽象类和接口区别?

    1. 抽象类可以有构造方法,接口没有
    2. 抽象类可以有普通成员变量,接口只有静态成员变量(public static final)
    3. 抽象类可以有非抽象的普通方法,接口所有方法都是抽象的(public abstract)
    4. 抽象类可以有静态方法,接口不能
    5. 类只能继承一个类,但可以实现多个接口
  6. String str=”aaa”,与 String str=new String(“aaa”)一样吗?

  7. 那针对浮点型数据运算出现的误差的问题,你怎么解决?

    使用BigDecimal计算,并使用String初始化

  8. 面向对象的特征有哪些方面?

  9. 访问修饰符 public,private,protected,以及不写(默认) 时的区别?

  10. Hashcode 的作用

    从HashMap角度看,JVM每new一个Object,它都会将这个Object丢到一个Hash表中去,这样的话,下次做Object的比较或者取这个对象的时候(读取过程),它会根据对象的HashCode再从Hash表中取这个对象。这样做的目的是提高取对象的效率。若HashCode相同再去调用equal。

    重写Hashcode一定要重写equals。

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

  12. String 和 StringBuilder、StringBuffer 的区别?

  13. 接口是否可继承(extends)接口?抽象类是否可实现(implements)接口?抽象类是否可继承具体类(concreteclass)?

    接口可以继承接口,而且支持多重继承。抽象类可以实现(implements)接口,抽象类可继承具体类也可以继承抽象类。

  14. 一个”.java”源文件中是否可以包含多个类(不是内部类)?有什么限制?

    可以包含,但是只可以有一个public类

Java集合

  1. ArrayList和LinkedList

  2. HashMap如何排序

    使用LinkedHashMap,它是HashMap的子类,可以直接被HashMap承接。

    LinkedHashMap使用了双向链表,支持自定义排序,也支持插入顺序排序。

  3. Vector,SynchronizedList,CopyOnWriteArrayList

    SynchronizedList读写操作都会加锁

    CopyOnWrite采用写时复制,写的时候通过复制一个新数组,防止阻塞读操作,读写操作在不同数组上。读读,读写不互斥,适合读多写少。占用内存较多。

  4. HashMap底层实现,put()操作,resize()操作

  5. ConcurrentHashMap,HashTable

  6. ArrayList遍历删除元素问题

    使用foreach方式删除,原理是使用迭代器,迭代器支持快速失败,一旦修改元素就会报错。

    可以使用直接for(int i = 0; i < n; i++) 的方式遍历删除,但是要注意删除的时候会略过一个元素,删除时要手动i--

Java异常

  1. finally中包含return语句

    会返回finally中的return导致try/catch中的return无效。因为程序会先运行finally再进行try/catch的retrun。

  2. Error 与 Exception 的区别

Java反射

  1. 动态代理

    jdk动态代理和cglib动态代理。jdk动态代理的类一定要实现接口,动态代理类实现InvocationHandler接口,再实现invoke(),再调用Proxy.newProxyInstance()获得代理类即可。

    jdk动态代理对象效率高,但是执行效率低,CGLib创建效率低但是执行效率高(直接修改字节码得到)。但是jdk动态代理效率越来越好,所以spring中通常使用jdk动态代理,不能使用再使用CGLib动态代理。

  2. 除了使用 new 创建对象之外,还可以用什么方法创建对象?

    1. 获得class对象,使用newInstance。ClassName.class.newInstance()
    2. 继承Cloneable接口,实现clone()方法
    3. 反序列化
  3. java 反射的作用

  4. 反射的使用步骤

    1. 获取 Class 对象:Class.forName()
    2. 获取对象方法/属性:classObject.getMethods()/getFields()
    3. 调用对象方法:method.invoke()

Java线程、进程、并发

  1. 线程和进程的关系

  2. 创建线程的方法

    1. 继承Thread
    2. 继承Runnable
    3. 继承Callable,有返回值
  3. 线程池的7个参数

  4. volatile的作用,线程安全单例模式实现,及其中volatile的作用

  5. notify()和notifyAll()区别

  6. Thread 类中的 start() 和 run() 方法有什么区别?

  7. sleep()和wait()区别

    • sleep()是Thread类的,阻塞但不会释放资源。
    • wait()是Object类的,阻塞且释放资源。
  8. sychronized和ReentrantLock

    • synchronized不可响应中断,Lock可以。

    • 都为可重入锁。

  9. 锁升级

    • 无锁,偏向锁,轻量级锁,重量级锁。

    • 以及Markword的锁字段和hashcode信息存储。

  10. 线程池的submit()和execute()

    • execute()只能提交Runnable对象,且返回void,主线程没有办法获取到异常信息。
    • submit()可以提交Runnable,Callable,可以返回Future对象获取结果以及异常信息。

JVM

  1. 64位JVM,int为多少字节

    4字节。

  2. GC如何分代

  3. 双亲委派模型

  4. 垃圾收集算法,重点关注CMS和G1

    CMS:增量标记

    G1: 原始快照

  5. JVM中的各个组成部分

    堆,本地内存,虚拟机栈,本地方法栈,程序计数器。

  6. 垃圾收集的三种基础算法

  7. JVM加载类的过程

    加载、连接(验证、准备、解析)、初始化。

  8. 什么时候会执行Minor GC和Full GC

  9. 从新生代晋升到老年代的条件

    1. 达到新生代最大年龄(默认15)
    2. 大对象直接分配到老年代
    3. 分配担保机制:新生代装不下,进行Minor GC后仍分不下。如果打开了分配担保,若历次新生代晋升老年代对象的平均值,则允许对象尝试直接晋升,若不足则出发Full GC;否则直接先进行Full GC。
    4. 动态对象年龄判断:若Survivor区中相同年龄的对象的所有大小之和超过Survivor空间的一半,年龄大于或等于该年龄的对象可直接进入老年代。

数据库

MySQL

  1. InnoDB和MyISAM

  2. 数据库三范式

    1. 第一范式(1st NF - 列都是不可再分)
    2. 第二范式(2nd NF- 每个表只描述一件事情)
    3. 第三范式(3rd NF- 不存在对非主键列的传递依赖)
  3. InnoDB事务的四个隔离级别

  4. 脏读,不可重复读,幻读

  5. ACID原则,如何保证

  6. 如何实现可重复读,解决脏读

  7. MVCC如何实现

    创建Read View,Read View包含四个字段:

    • 创建当前事务的事务id
    • 还未提交的事务id列表
    • 还未提交的事务id列表中最小的事务id
    • 下一个要开启的事务id(不在列表中)
  8. 如何解决幻读

    Next-Key Lock = 间隙锁 + 行锁

  9. InnoDB底层存储格式

    B+树,每个节点就是一个数据页,数据页内有页目录、最小记录、数据、最大记录。页内通过二分查找页目录定位到数据所在的分组(槽),在分组内进行遍历查找(分组限制了大小,防止链表过长)。

  10. B+树的数据结构,为什么不用B树。

    从磁盘IO次数进行考虑。

  11. B+树和红黑树和二叉平衡树(AVL树)

  12. MySQL中的索引类型

    按不同类型划分:

    1. 数据的存储方式:聚集索引、非聚集索引
    2. 索引包含的列数:单列索引、联合索引
    3. 字段特性:主键索引、唯一索引、前缀索引、普通索引
  13. Hash索引和B+树索引

    Hash索引不支持范围查询。

  14. 索引失效的场景

    • 隐式类型转换
    • 模糊匹配
    • or的左右不都含有索引
    • 函数计算(新版本支持对函数建立索引)
    • 表达式计算
    • 联合索引最左匹配原则
  15. 为什么主键索引最好是自增的

    防止页分裂导致内存碎片,导致结构不紧凑影响查询效率。

  16. MySQL死锁的发生和解决

    发生:并发插入的时候,两方插入了间隙锁,两方请求插入意向锁。

    间隙锁和间隙锁是可以重叠的,插入意向锁和间隙锁是互斥的。

  17. undolog

    undolog不会进行刷盘,它是记录在redolog里面的。重启后,由redolog恢复出undolog的数据再对未提交的事务进行回滚。

    undolog和脏数据一起刷新到磁盘。

    undolog其实也是以页的形式(和数据一样的形式)存储在Buffer Pool中,保证redolog落盘后,undolog和脏页才会落盘。

  18. redolog

    redolog是循环写的,若满了会阻塞MySQL,把脏页写回磁盘然后移动checkpoint。

  19. binlog

    binlog可用于全量恢复数据。

  20. redolog的刷盘时机和binlog的刷盘时机

    redolog有可能在事务执行中进行刷盘。

    binlog一定是事务提交后才刷盘。

  21. 两阶段提交过程和原因

    以binlog为主。

  22. 一条更新语句执行的过程

Redis

  1. redis的使用场景

  2. redis的原理

    单线程,多路复用。

  3. redis和memcached

  4. redis是严格单线程吗

    redis把生成快照等耗时操作交给了后台线程。

    6.0后把对socket的读写也交给了后台IO线程。

  5. redis的5种基本数据结构以及实现方式

  6. redis持久化:AOF和RDB的优缺点及实现

  7. 混合持久化RDB+AOF

  8. 过期删除策略

    分为volatile和all以及noeviction。

  9. 内存淘汰策略

    惰性删除,定期删除。

  10. 缓存常见的几个问题:

    • 缓存雪崩:大量缓存同时失效,设计随机过期时间,加锁防止请求大量落到数据库上。
    • 缓存击穿:热点数据失效,加锁防止请求大量落到数据库;设置永不过期。
    • 缓存穿透:数据库没数据,使用Bloom Filter或者设置段时间的null值。
  11. 如何保证缓存和数据库的一致性

    先更新数据库,再删除缓存。

  12. Redis支持原子性吗

    不支持,但只是不支持回滚而已。

  13. Redis集群

    • 主从复制:读写分离。
    • 哨兵(Sentinel)模式:哨兵使用Raft选举算法,选出leader进行主从节点故障转移。
    • 切片(Sharding):使用16384个哈希槽。

计算机网络

  1. OSI七层以及TCP/IP四层,以及没层对应的作用。

  2. 输入网址到网页显示,期间发生了什么

  3. HTTP 1.0/1.1/1.2/1.3 每一个版本的区别以及提升

  4. HTTPS的握手过程(RSA和ECDHE两种)

  5. 证书验证的过程,以及递归证书验证。

  6. TCP三次握手、四次挥手

  7. 为什么需要三次握手、为什么需要四次挥手

  8. 四次挥手的每个状态,time-wait为什么2MSL

  9. TCP流量控制

    窗口关闭:客户端使用窗口探测报文;服务端使用窗口通告报文

    糊涂窗口综合症:

    • 客户端使用Nagle算法,避免发送小数据。
    • 服务端避免通告小窗口。
  10. TCP拥塞控制

    • 慢启动
    • 拥塞避免
    • 拥塞发生
    • 快速回复(快重传)
  11. TCP半连接队列和全连接队列

  12. Syn Flood攻击如何解决

    队列无法加入的时候返回syn cookie。

  13. 粘包问题

    • 固定长度的消息。
    • 特殊字符作为边界。
    • 自定义消息结构。
  14. DNS

  15. ARP

  16. ICMP(ping使用的报文)

  17. IP地址分类;无分类地址CIDR

操作系统

  1. 进程和线程的区别

  2. 进程通信的方式

  3. 进程有几种状态以及状态间的转换

  4. 死锁发生的四个必要条件

  5. 解决死锁的方法:

    • 预防:破坏4个条件中的一个,对应用的影响最大。
    • 避免:如银行家算法,尝试分配,若分配后,剩余资源可以让其他进程完成,则分配,否则不分配。
    • 检测:检测系统中是否出现死锁。
    • 解除:检测到死锁后,对死锁进行操作,如放弃某一进程,释放资源。
  6. 进程调度算法

    • SJF:短作业优先

    • FCFS:先来先服务

    • HRRN(Highest Response Ratio Next):高响应比优先

      优先级 = (等待时间 + 要求服务时间)/ 要求服务时间

      • 等待时间越长,优先级越高
      • 等待时间相同时,要求服务时间越短,优先级越高
    • RR(Round Robin):时间片轮转

    • HPF(Highest Priority First):高优先级优先

    • Multilevel Feedback Queue:多级反馈队列

      每个队列优先级不同,单独队列中为时间片轮转算法,用完时间片还没有完成,则进入下一队列

  7. 内存管理,虚拟内存

  8. 内存分页和内存分段的结构,页表和段表的结构

  9. 为什么会有多级页表

  10. 段页式存储

  11. TLB是什么

    Translation Lookaside Buffer,简称快表,其实就是页表缓存,当在页表缓存找不到时才去页表查找。

    页表存储在内存中。

    缓存比内存快。

  12. 页表换入换出的过程,什么是Swap机制

  13. 在 32 位/64 位操作系统环境下,申请的虚拟内存超过物理内存后会怎么样?

    • 在 32 位操作系统,因为进程最大只能申请 3 GB 大小的虚拟内存,所以直接申请 8G 内存,会申请失败。
    • 在 64 位操作系统,因为进程最大只能申请 128 TB 大小的虚拟内存,即使物理内存只有 4GB,申请 8G 内存也是没问题,因为申请的内存是虚拟内存。

    程序申请的虚拟内存,如果没有被使用,它是不会占用物理空间的。当访问这块虚拟内存后,操作系统才会进行物理内存分配。

    如果申请物理内存大小超过了空闲物理内存大小,就要看操作系统有没有开启 Swap 机制:

    • 如果没有开启 Swap 机制,程序就会直接 OOM;
    • 如果有开启 Swap 机制,程序可以正常运行。
  14. 内存页面置换算法

    • 最佳页面置换算法
    • 先进先出算法
    • LRU
    • 时钟页面置换算法
    • 最不常用算法
全部评论

相关推荐

点赞 评论 收藏
分享
1 12 评论
分享
牛客网
牛客企业服务