20211012面试题总结

1、synchornized与lock区别 ?

  • 从层级上看:

    • synchronized是java内置关键字,在jvm层面
    • lock是一个接口,有丰富的API,可以通过实现接口,如reentrantLock
  • 从扩展性上看:

    • synchronized相对扩展性差点

    • Lock更适合扩展:

      (1)锁粒度可以控制,可以灵活的调用方法释放锁

      (2)通过继承AQS进行对应业务的修改,扩展

      (3)synchronized无法判断是否获取到锁

  • 锁的性质:

    • synchronized是可重入,不可中断,非公平的
    • Lock锁是可重入的,可以中断,可以通过参数设置公平锁/非公平锁
  • 使用场景

    • synchronized锁适合代码少量的同步问题,lock适合大量同步的代码的同步问题
    • synchronized代码编写场景更丰富写,Lock相对单一
  • synchronized 会自动释放锁,Lock需要我们手工释放锁

  • 性能

    1.6之前,Lock快,1.6之后对synchronized进行了锁升级的优化,性能上差不太多

拓展:

为什么说Lock比synchronized快?

  • synchronized基于底层操作系统的Mutex Lock实现,因此每次获取和释放锁操作都会带来用户态,内核态的切换,从而增加系统性能消耗。

synchronized锁升级的过程?

  • 主要方向为 无锁、偏向锁、轻量级锁、重量级锁
  • 对象初始化时为无锁的状态
  • 当有线程进行锁竞争时,会在对象头的markword中记录下该线程id(如果该对象已经被hashcode了,此时就不会存在markword中,也就是说如果对象被hashcode,那么就不会进入偏向锁的状态,而是直接膨胀为轻量级锁),此时进入偏向锁
  • 当有不同线程进行锁竞争时,会利用CAS尝试获取锁,此时为轻量级锁
  • 当自旋次数超过一定次数后,会升级为重量级锁,此时其他线程进入阻塞,等待锁释放。

2、volatile关键字有什么用处?

volatile主要有两个功能

  • 第一保证线程间的可见性。用volatile修饰的变量,当一个线程修改时,其他线程也能看到修改结果。

  • 第二禁止指令重排序。在JVM底层实现时,是有可能发生指令重排的。以创建对象为例

    (1)初始化对象,对象属性赋初始值 (2)属性赋值 (3)指针指向该对象

    如果发生(2)(3)指令重排,那么就会出现一个问题。用户获取到的是一个半初始化的对象。所以一般我们创建单例时会加上volatile修饰。

3、HashMap底层数据结构是什么?扩容机制是如何实现的?HashMap怎么解决碰撞问题的?

HashMap底层数据结构1.7以及1.7之前 是通过数组+链表的方式 1.8之后 也是数组+链表,只不过当链表数量过长会进化为红黑树

HashMap的扩容机制:首先HashMap会有个初始容量 为 16 ,影响因子为 0.75,当HashMap中元素个数超过 容量* 影响因子 时会触发扩容 resize(). resize会扩大容量为当前的两倍,然后将目前已有的数据拿出来 重新计算hash,并放入到新的 数组中。

HashMap解决Hash碰撞:

1.减少Hash碰撞的几率。通过 hash ^ hash>>>16 将高位特征与低位混合,使得Hash能够更加散列,另外在put的时候 将hash & (length-1) 这样更进一步的减少了碰撞的几率

2.如果发生碰撞:会利用拉链表,将碰撞数据利用链表 或者红黑树放到数组对应的位置后

扩展:为什么影响因子是0.75

在HashMap的源码中有这么一段描述,根据泊松分布,负载因子是0.75的时候,空间利用率比较高,而且避免了相当多的Hash冲突,使得底层的链表或者是红黑树的高度比较低,提升了空间效率。

4、设计模式有哪些?你实际使用过哪些?

​ 有一个利用FLink进行数据清洗的项目,因为基本都是数据库操作,需要写一些sql,但是flink tableAPI使用起来不太友好,所以使用了底层的API,然后自己写sql。编写sql的过程中仿照mybatis进行了一些封装。使用了包括工厂模式 来创建xml的解析处理类。使用代理模式,利用动态代理,获取dao层的代理对象。

5、线程池的几个核心参数是什么?

  • 核心线程数
  • 最大线程数
  • 线程工厂
  • 线程留存时间
  • 线程留存时间单位
  • 工作队列
    • LinkedBlockingQueue
    • ArrayBlockingQueue 指定大小
    • PririBlockingQueue 优先级队列
    • DelayedWorkQueue 按照时间排序
  • 拒绝策略
    • AbortPolicy 直接排除reject异常 这也是默认的一种策略
    • CallerRunsPolicy 由调用者执行
    • DiscardPolicy 直接丢弃这个任务
    • DiscardOldestPolicy 丢弃队列中最老的任务

6、JVM内存溢出如何排查问题?

首先在生产环境下 最好都配置上 -XX:+HeapDumpOnOutOfMemoryError 表示出现OOM异常时,生成堆快照hprof文件

可以依赖一些常用的工具进行快照内容的查看如jconsle,在 jconsle中有关于堆中创建对象的统计,可以看到这些对象的数量,进而确定是哪个对象一直没被释放。如果确实需要,可以适当调整jvm内存大小,防止OOM溢出(有一次做Flink任务时,每次执行过后发现总是会报OOM,然后再FLink控制台观察了下,当时分配的内存为500M,然后Full GC比较频繁。就利用堆快照进行了分析,发现有个对象没有使用单例,导致创建过多。调整代码之后发现还是有问题,就将内存上调至 1G。上调到1G之后发现,稳定在500-600M左右)

7、怎么做JVM调优?

首先是对JVM参数的一些调整,包括启动时堆内存的初始化 -Xms 最大堆内存 -Xmx

观察GC情况,如果出现频繁YGC,可以调整年老代年轻代大小划分,或者考虑更换垃圾回收器

8、Spring Cloud组件有哪些,自己对哪个最了解,讲解一下?

注册中心:eureka、nacos

配置中心:spring config

网关:zuul,spring gateway

负载均衡:ribbon

断路器:hystrix

远程调用:fegin,dubbo rpc

分布式事务:alibaba senta

链路追踪:springcloud-sleuth

9、简要描述sql语句执行过程

词法分析器、语法分析器

通过连接器,连接到数据库。如果是查询语句,5.6之前会有查询缓存,如果是5.6之后,查询缓存会默认关闭,8已经完全剔除了查询缓存,因为数据变化量大了时候,查询缓存存在的意义并不大。

通过连接器之后,调用分析器 对 词法、语法进行分析。词法分析包括 关键字是否拼写错误,表名、列名是否存在等。语法分析 包括 sql拼写顺序是否有误。如果这个阶段判断出来有问题,那么会直接返回报错。

经过分析器之后调用优化器,此时会对sql进行优化,包括对索引使用的判断,优先执行语句等。

最后通过执行器进行sql语句的执行,并返回结果

10、Mysql搜索引擎有哪些,有什么区别

常见的Mysql搜索引擎有InnoDB,MyISAM

MyISAM与InnoDB的区别

  • 存储结构的不同
    • MyISAM每个表会被放在三个文件中:表格定义、数据文件、索引文件
    • 所有的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间文件)
  • 存储空间
    • MyISAM可以被压缩,存储空间较小
    • InnoDB的表需要更多的内存和存储,它会在主内存中建立其专用的bufferpool用于高索缓存数据和索引
  • InnoDB支持事务,MyISAM不支持事务
  • MyISAM只能进行表级锁定,InnoDB支持行级锁,表级锁,锁的粒度小并发能力高
  • MyISAM的索引与数据时分开存储的,索引需要多寻址一次。InnoDBB+树中的叶子节点可以存储行数据

11、SQL优化思路

由小到大 -> 数据量大了之后考虑分库分表-> Hbase

  • 从sql入手
    • 避免使用 select *
    • 尽量使用覆盖索引
    • 注意查询字段的类型,减少隐式转换
    • 使用exist 代替 in
    • 使用not exist 代替 <>
  • 对sql进行explain,观察是否走索引,尽量使查询能够走索引
  • 数据量如果过大,对于oracle可以考虑分区,Mysql可以考虑分库分表

12、binlog、redolog,有什么区别?

从层级看:binlog属于server层、redolog属于数据引擎层

从记录内容看:binlog记录逻辑日志,需要记录更新的过程、redolog记录物理日志,只关注结果,记录该数据页更新状态

写日志的方式:redolog是通过循环写,checkpoint进行擦除,write pos进行写入更新。日志大小固定。

binlog 日志追加,上限收服务器影响

用途:redolog与事务相关,可以在服务器发生异常后,做事务数据的自我恢复

binlog主要做主从复制以及数据恢复,没有自动恢复的能力

13、是否用过分库分表、主流的分库分表如何选型?

​ MyCat、ShardingJDBC

mycat是一个中间件代理层,对研发无感知

1、一个彻底开源的,面向企业应用开发的大数据库集群

2、支持事务、ACID、可以替代MySQL的加强版数据库

3、一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群

4、一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server

5、结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品

6、一个新颖的数据库中间件产品

优点:
1、开发无感知
2、增删节点程序不需要重启
3、跨语言(java 、php)
缺点:
1、性能下降没因为多了一层
2、不支持跨数据库

shardingjdbc

定位为轻量级Java框架,在Java的JDBC层提供的额外服务。 它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架。

1、适用于任何基于JDBC的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC。

2、支持任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, Druid, HikariCP等。

3、支持任意实现JDBC规范的数据库。目前支持MySQL,Oracle,SQLServer,PostgreSQL以及任何遵循SQL92标准的数据库。

优点:
1、性能很好的
2、支持跨数据库jdbc
缺点:
1、增加了开发难度
2、不支持跨语言(java)

14、Redis的5种基础数据类型及其对应数据结构?

  • String
  • List
  • hash
  • Set
  • sorted-set

15、树、链表、数组,查询时间复杂度分别是多少?

树由于有分叉,每次查询一般只会走一个分叉,因此时间复杂度为O(logn)

数据只需要知道下角标就可以直接查询到数据,因此时间复杂度为O(1)

链表由于需要从头节点向后遍历,因此时间复杂度为O(n)

16、设计一个"秒杀系统",讲一下如何实现,使用哪些技术,有什么注意点?

首先考虑静态页面的预加载,可以预先加载到nginx中,同时也可以利用nignx进行负载均衡

使用hystrix进行流量的限流、利用消息队列进行流量削峰

利用Redis实现分布式锁,用于库存修改。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值