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实现分布式锁,用于库存修改。