中高级Java程序员,你不得不掌握的基本功,挑战20k+

Posted 緈諨の約錠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了中高级Java程序员,你不得不掌握的基本功,挑战20k+相关的知识,希望对你有一定的参考价值。

文章目录

1 前言

工作久了就会发现,基础知识忘得差不多了。为了复习下基础的知识,同时为以后找工作做准备,这里简单总结一些常见的可能会被问到的问题。

2 自我介绍

自己根据实际情况发挥就行

3 Java SE

3.1 Java访问控制修饰符

Java访问控制修饰符

3.2 Java中抽象类与接口有何区别?

Java中抽象类与接口

3.3 Java中super关键字与final关键字

Java中super关键字与final关键字

3.4 final修饰的对象,有几种初始化方式

final修饰的对象,有几种初始化方式

3.5 Java中方法的重载(Overload)与方法的覆盖(Override)

Java中方法的重载与方法的覆盖

3.6 Java基础知识总结,干货来啦

Java基础知识总结,干货来啦

3.7 Java基础面试题干货系列(一)

Java基础面试题干货系列(一)

3.8 Java中的String是不可变的,Why?

Java中的String是不可变的,Why?

3.9 Java反射基础入门,一篇就够啦

Java反射基础入门,一篇就够啦

3.10 面向对象与面向过程

面向对象与面向过程

3.11 Java基础面试题干货系列(二)

Java基础面试题干货系列(二)

3.12 理解Java中的多态机制,一篇就够啦

理解Java中的多态机制,一篇就够啦

3.13 Java中参数传递(值传递还是引用传递)

Java中参数传递(值传递还是引用传递)

3.14 Java编程思想之高内聚低耦合

Java编程思想之高内聚低耦合

3.15 Java基础面试题干货系列(三)

Java基础面试题干货系列(三)

3.16 Java中的异常(Exception)

Java中的异常(Exception)

3.17 Java中设计模式的七大基本原则

Java中设计模式的七大基本原则

3.18 Java中File类,你知道有哪些api方法吗?

Java中File类,你知道有哪些api方法吗?

3.19 计算机中字节、字、位、bai比特等单位之间的换算关系

计算机中字节、字、位、bai比特等单位之间的换算关系

3.20 HTTP请求状态码对照表

HTTP请求状态码对照表

3.21 集合

3.21.1 集合顶层的接口类有哪些?集合常见的有哪几种?都有啥区别?

集合类图:

  • Collection接口
  • Map接口

3.21.2 集合顶层的接口类有哪些?

集合的顶层接口,常见的主要有: Collection接口Map接口

3.21.3 集合常见的有哪几种?

和Collection相关的接口主要有: CollectionListSet接口

  • Collection接口
    Collection是一个抽象出来的接口,定义如下:

    public interface Collection<E> extends Iterable<E> {}
    

    其中包括了集合的基本操作,包括: 删除添加遍历大小

  • List接口
    List接口继承自Collection,List中的元素的有序且允许重复的。定义如下:

    public interface List<E> extends Collection<E> {}
    
  • Set接口
    Set接口继承自Collection,Set是数学中定义的集合,元素无需不允许重复。定义如下:
    public interface Set extends Collection {}

Map接口,也是顶层接口,Map保存的是键值对映射,映射关系可以是一对一或者一对多。

参考资料: https://blog.csdn.net/weixin_34176694/article/details/88708182

3.21.4 请说明Collection和Collections的区别

Collection是集合类的顶级接口,继承与他的接口主要有List和Set。而Collections是针对集合类的一个工具类,它提供了一系列的静态方法实现对各种集合的搜索、排序、线程安全化等操作。

3.21.5 ArrayList和Vector以及LinkedList三者有啥区别?

  • ArrayList 和Vector底层都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快

  • 请说明ArrayList和LinkedList的区别?
    ArrayList和LinkedList都实现了List接口,ArrayList是基于索引的数据接口,它的底层是数组。它可以以O(1)时间复杂度对元素进行随机访问。而LinkedList是以元素列表的形式存储它的数据,每一个元素都和它的前一个和后一个元素链接在一起,在这种情况下,查找某个元素的时间复杂度是O(n)。LinkedList的插入,添加,删除操作比ArrayList速度更快,因为当元素被添加到集合任意位置的时候,不需要像数组那样重新计算大小或者是更新索引。LinkedList比ArrayList更占内存,因为LinkedList为每一个节点存储了两个引用,一个指向前一个元素,一个指向下一个元素。

3.21.6 HashMap和HashTable有何区别?

  • HashTable
    底层数组+链表实现,无论key还是value都不能为null,线程安全,适合于多线程环境,实现线程安全的方式是在修改数据时锁住整个HashTable,效率低,ConcurrentHashMap做了相关优化

    初始size为11,扩容:newsize = olesize*2+1

    计算index的方法:index = (hash & 0x7FFFFFFF) % tab.length

  • HashMap
    底层数组+链表实现,可以存储null键和null值,线程不安全,更适合于单线程环境

    初始size为16,扩容:newsize = oldsize*2,size一定为2的n次幂

    扩容针对整个Map,每次扩容时,原来数组中的元素依次重新计算存放位置,并重新插入
    插入元素后才判断该不该扩容,有可能无效扩容(插入后如果扩容,如果没有再次插入,就会产生无效扩容)

    当Map中元素总数超过Entry数组的75%,触发扩容操作,为了减少链表长度,元素分配更均匀

    计算index方法:index = hash & (tab.length – 1)

更详细的介绍,可参考我的另一篇博客: HashMap、Hashtable、ConcurrentHashMap的区别和原理浅析

3.21.7 HashTable和ConcurrentHashMap有何区别?

  • 相同点
    Hashtable和HashMap都实现了Map接口,两者都是线程安全的

  • 不同点
    Java5提供了ConcurrentHashMap,它是HashTable的替代,ConcurrentHashMap比HashTable的扩展性更好,性能也大大提升了

  • 为什么说ConcurrentHashMap性能大大提高了?

    简单来说,ConcurrentHashMap底层有分段锁,类似于mysql中的行级锁,而Hashtable是锁整个hash表,类似于mysql中的表级锁

    ConcurrentHashMap提供了与Hashtable和SynchronizedMap不同的锁机制。Hashtable中采用的锁机制是一次锁住整个hash表,从而在同一时刻只能由一个线程对其进行操作,而ConcurrentHashMap是使用了锁分段技术来保证线程安全的,是一次锁住一个桶。

    ConcurrentHashMap默认将hash表分为16个桶,诸如get、put、remove等常用操作只锁住当前需要用到的桶。这样,原来只能一个线程进入,现在却能同时有16个写线程执行,并发性能的提升是显而易见的。

    锁分段技术: 首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问

3.21.8 ConcurrentHashMap底层实现原理

  • 底层采用分段的数组+链表实现,是线程安全的

  • 通过把整个Map分为N个Segment,可以提供相同的线程安全,但是效率提升N倍,默认提升16倍。(读操作不加锁,由于HashEntry的value变量是 volatile的,也能保证读取到最新的值。)

  • Hashtable的synchronized是针对整张Hash表的,即每次锁住整张表让线程独占,ConcurrentHashMap允许多个修改操作并发进行,其关键在于使用了锁分离技术

  • 有些方法需要跨段,比如size()和containsValue(),它们可能需要锁定整个表而而不仅仅是某个段,这需要按顺序锁定所有段,操作完毕后,又按顺序释放所有段的锁

  • 扩容:段内扩容(段内元素超过该段对应Entry数组长度的75%触发扩容,不会对整个Map进行扩容),插入前检测需不需要扩容,有效避免无效扩容

3.21.9 ThreadLocal底层是如何实现的

4 Java EE

4.1 UML类和类之间的关系详解

UML类和类之间的关系详解

4.2 UML图使用详解

UML图使用详解

Spring Boot和Spring Cloud有什么区别?

10、Spring MVC执行流程?

11、对Spring Ioc和Aop理解?

12、Spring 事务传播行为有哪些?有什么区别?

13、说一下动态代理和静态代理有何区别?动态代理有JDK动态代理和Cglib动态代理,这两个代理如何实现的,有何区别?

5 设计模式

14、项目中用到了那些设计模式?哪些好的框架里面有使用过这些设计模式?

6 MySQL总结

6.1 Java JDBC编程

Java JDBC编程

6.2 MySQL使用总结以及MySQL性能优化

MySQL使用总结以及MySQL性能优化

6.3 MySQL四大特性是什么(MySQL事务的基本要素(ACID)有哪些)?

  • 原子性(Atomicity)
    事务开始后所有操作,要么全部做完(要么都成功),要么全部不做(要么都失败),不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。

  • 一致性(Consistency)
    事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。

  • 隔离性(Isolation)
    同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程中,B不能向这张卡转账。

  • 持久性(Durability)
    事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。

6.4 MySQL隔离级别有几种,有什么区别?

6.4.1 MySQL四种隔离级别

MySQL默认的隔离级别是可重复读(repeatable-read),MySQL事务隔离级别有以下四种:

事务隔离级别脏读不可重复读幻读
读未提交(read-uncommitted)
读已提交(read-committed)
可重复读(repeatable-read)
串行化(serializable)

6.4.2 MySQL事务的并发问题

  • 脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据

  • 不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。

  • 幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。

  • 小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表

    具体示例,可以参考我另一篇博客: https://blog.csdn.net/smilehappiness/article/details/119656138

6.5 MySQL索引,主键索引与普通索引区别?

6.6 B+Tree索引结构底层实现原理?

6.7 MySQL如何进行性能优化?

6.8 MySQL什么情况下索引会失效?

7 JDK和JVM总结

8、Java8新特性有哪些?
Stream api,函数作为参数传递
26、Jvm垃圾回收、老年代、新生代、双亲委派模型等,以及JVM参数优化

27、如何阻止gc垃圾回收?

8 多线程总结

9、单Spring boot应用线程有几种同步方式?
synchronized,CountDownLatch
33、多线程如何使用的?
自定义线程池、Executors工具类四种线程池区别?

9 分布式技术总结

9.1 Redis缓存穿透 && 缓存击穿 && 缓存雪崩

9.1.1 缓存处理流程

前台请求,后台先从缓存中取数据,取到直接返回结果,取不到时从数据库中取,数据库取到更新缓存,并返回结果,数据库也没取到,那直接返回空结果。

Created with Raphaël 2.3.0 开始 Redis缓存中是否有数据 返回正常数据 结束 数据库中是否有数据 更新缓存数据 返回空数据 yes no yes no

9.1.2 Redis缓存穿透

缓存穿透是指大量不存在的key请求,由于缓存没有,便开始查询数据库,但数据库也没有查到数据,比如一些恶意攻击、爬虫等造成大量空命中。即:缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,会导致数据库压力过大,甚至宕机

解决方案:

  • 方案一: 缓存空结果,对数据库查询不存在的数据仍然记录在缓存中缓存一条数据,比如缓存一条空值 unknow,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用不存在的key暴力攻击,这样能有效的减少查询数据库的次数。(无论如何,要保证数据库的可用性

  • 方案二: 使用布隆过滤器

9.1.3 Redis缓存击穿

缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力导致数据库不可用的现象。

高并发条件下,对于热点数据(一般地,80%的情况下都是访问某些热点数据,也就是访问某些热点key,其他key访问会比较少),当数据缓存失效的一瞬间,或者刚开始时缓存中还没有对热点数据进行缓存,所有请求都被发送到数据库去查询,导致数据库被压垮。

解决方案:

  • 方案一: 使用全局互斥锁,就是在访问数据库之前都先请求全局锁,获得锁的那个才有资格去访问数据库,其他线程必须等待。由于现在的业务都是分布式的,本地锁没法控制其他服务器也等待,所以要用到全局锁,比如分布式锁。

  • 方案二: 对即将过期的数据主动刷新,比如起一个后台定时任务轮询,主动更新缓存数据,保证缓存不会全部失效。

  • 方案三: 设置热点数据永远不过期

9.1.4 Redis缓存雪崩

缓存雪崩是指:比如我们给所有的数据设置了同样的过期时间,然后在某一个历史性时刻,整个缓存的数据全部过期了,然后瞬间所有的请求都落到数据库,数据库被压垮,或者是缓存发生故障,导致所有的请求都落入到数据库,数据库被压垮

简单来说就是,缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至宕机。和缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库,缓存雪崩更加的严重。

缓存雪崩的核心就是你的缓存不能用了,不能用了包含两种情况:
突然有一个高并发请求:

  • 我要查的数据都没有缓存,那么都查询数据库,数据库可能被查询宕机
  • 缓存本身就不能用了,比如缓存宕机了,那么也导致所有请求都查询数据库,数据库宕机

解决方案:
事前:

  • redis要高可用(搭建集群或者主从哨兵),避免redis不可用
  • 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生
  • 如果缓存数据库是分布式部署,将热点数据均匀分布在不同的缓存数据库中

事中:

  • 本地ehcache缓存(mybatis二级缓存)+限流&降级(比如返回:系统繁忙,请稍后再试或者网络开小差了等等),避免数据库被压垮
  • 也可以使用极端的处理,把热点数据设置为-1,即永远不过期

事后: redis持久化,快速恢复缓存数据

9.2 Redis系列-Java面试题干货系列(四)

Redis系列问题总结

9.3 分布式保证系统数据一致性,如何使用的分布式锁?有哪几种方式?

基于Redis实现分布式锁
基于Zookeeper实现分布式锁

16、redis有哪些数据类型?项目中使用了那些场景?

18、分布式事务怎么实现的?

18、使用了消费组件有哪些?有哪些组件类?延迟队列有使用过吗?消息丢失怎么处理?
rabbitmq,
20、nginx如何实现不同资源的转发访问?

21、nginx如何实现负载均衡,有哪几种方式?
24、Elasticsearch底层实现原理?
倒排索引

10 微服务总结

19、Spring Cloud使用了那些组件?负载均衡如何实现的?如何鉴权?
nacos、zuul、gateway网关、ribbon、feign、hystrix,基于ribbon实现动态负载均衡,基于nginx实现静态负载均衡

22、nacos服务注册如何实现的?

23、nacos服务配置动态刷新如何实现?底层如何实现的?
@RefreshScope,注解底层是使用cglib动态代理来实现,而cglib是创建动态子类继承来完成功能的增强

如何使用Hystrix进行熔断降级?
如果A服务调用B服务、然后调用C服务,假设C服务故障无法响应

如何抗住高并发?
单应用服务A,可以进行业务细粒度的拆分,比如说crm系统,可以拆分为客户服务、订单服务、附件服务等,每个细粒度的应用服务,又可以进行多实例集群,这样就可以提高系统的吞吐量

高并发海量数据,如何处理?
分库分表(横向拆分:按省份,每个省份一个库,每个库再分多个订单表,比如0_order、1-order等,当然了,也可以对6556进行取余,余数作为库名,比如0_order、1_order,库划分好了,再分多个表,进行读写分离)

11 项目问题总结

11.1 Git使用总结

Git使用详解

15、项目中遇到问题,如何排查?
25、解决线上bug问题,举一个印象最深刻的例子?
多次提交,重复数据问题,基于token做幂等校验
线上问题不能及时反馈,添加钉钉预警及时触达

12 数据结构和算法

13 Linux常用命令有哪些

Linux crontab 命令
Linux怎样使用top命令查看系统状态

14 前端问题

34、Vue生命周期函数有哪些?React生命周期函数有哪些?

15 有什么想要问的吗?

1、如果有幸加入的话,主要负责的项目是什么?
2、咱们项目用到了什么技术、架构?

写博客是为了记住自己容易忘记的东西,另外也是对自己工作的总结,希望尽自己的努力,做到更好,大家一起努力进步!

如果有什么问题,欢迎大家一起探讨,代码如有问题,欢迎各位大神指正!

给自己的梦想添加一双翅膀,让它可以在天空中自由自在的飞翔!

以上是关于中高级Java程序员,你不得不掌握的基本功,挑战20k+的主要内容,如果未能解决你的问题,请参考以下文章

中高级Java程序员,你不得不掌握的基本功,挑战20k+

中高级Java面试中你不得不会的知识点,项目实战

成为高级程序员不得不了解的并发

学习大数据需要掌握的知识(不得不看)

带你全面掌握高级知识点!java语言程序设计与数据结构基础篇

学习Java并发编程之前你不得不知道的那点事