面试总结2
创始人
2024-03-12 22:39:48

用时:40min

  • 自我介绍
  • hashset存储对象怎么进行判断是否重复
  • Synchronized底层实现原理

  • Synchronized锁的升级过程

  • 讲讲开发中常用到的spring注解
  • spring事务,传播机制,隔离级别
  • 说一说你常用的git命令
  • 说一说你对IOC、AOP的理解

1、hashset存储对象怎么进行判断是否重复

HashSet  根据每个对象的哈希码值(调用hashCode()获得)用固定的算法算出它的存储索引,把对象存放在一个叫散列表的相应位置(表元)中:

  • 存对象时,hashSet集合首先调用该对象的hashCode方法来获得该对象的hashCode值,与hash表中的值进行比较。如果不存在,则直接把该对象存入集合中,并把该hashCode值存入hash表中,此次add操作结束。如果存在,则进行下面的计算。

  • 通过”==”操作符判断已经存入的对象与要存入的对象是否为同一对象。如果true则集合认为添加相同对象,add失败。如果false(不是同一对象)则进行下面的计算。(这一条很重要,保证了,不管如何操作,在HashSet中都不可能存入同一个对象两次)

  • 调用要添加的对象的equals()方法,并把集合中的另一元素作为参数传入,如果返回值为true则集合认为添加相同对象,add失败。否则添加成功。

2、Synchronized底层实现原理

同步方法通过ACC_SYNCHRONIZED 关键字隐式的对方法进行加锁。当线程要执行的方法被标注上ACC_SYNCHRONIZED时,需要先获得锁才能执行该方法。
同步代码块通过monitorenter和monitorexit执行来进行加锁。当线程执行到monitorenter的时候要先获得锁,才能执行后面的方法。当线程执行到monitorexit的时候则要释放锁。每个对象自身维护着一个被加锁次数的计数器,当计数器不为0时,只有获得锁的线程才能再次获得锁。 

3、Synchronized锁的升级过程

Java SE 1.6 为了减少获得锁和释放锁带来的性能消耗,引入了 “偏向锁” 和 “轻量级锁”:锁一共有 4 种状态,级别从低到高依次是:无锁状态、偏向锁状态、轻量级锁状态和重量级锁状态。锁可以升级但不能降级。

偏向锁:大多数情况下,锁不仅不存在多线程竞争,而且总是由同一线程多次获得,为了让线程获得锁的代价更低而引入了偏向锁。当一个线程访问同步块并获取锁时,会在对象头和栈帧中记录存储锁偏向的线程ID,以后该线程在进入同步块时先判断对象头的Mark Word里是否存储着指向当前线程的偏向锁,如果存在就直接获取锁。

轻量级锁:当其他线程尝试竞争偏向锁时,锁升级为轻量级锁。线程在执行同步块之前,JVM会先在当前线程的栈帧中创建用于存储锁记录的空间,并将对象头中的MarkWord替换为指向锁记录的指针。如果成功,当前线程获得锁,如果失败,标识其他线程竞争锁,当前线程便尝试使用自旋来获取锁。

重量级锁:锁在原地循环等待的时候,是会消耗CPU资源的。所以自旋必须要有一定的条件控制,否则如果一个线程执行同步代码块的时间很长,那么等待锁的线程会不断的循环反而会消耗CPU资源。默认情况下锁自旋的次数是10 次,可以使用-XX:PreBlockSpin参数来设置自旋锁等待的次数。10次后如果还没获取锁,则升级为重量级锁。

补充:synchronized锁表现三种形势

Java中每个对象都可以作为锁。具体表现为以下3种方式:

  1. 对于普通方法,锁的是当前实例对象
public class SynchronizedTest {public synchronized void test(String name){System.out.println(name+"开始执行");try {Thread.sleep(2000);}catch (Exception e){}System.out.println(name+"执行完毕");}public static void main(String[] args) throws  Exception {SynchronizedTest t=new SynchronizedTest();new Thread(new Runnable() {@Overridepublic void run() {t.test("线程1");}}).start();SynchronizedTest t1=new SynchronizedTest();new Thread(new Runnable() {@Overridepublic void run() {t1.test("线程2");}}).start();}
}

 上面这个代码我们new了两个不同的对象。打印结果如下。线程2并没有等线程1执行完成后才执行,说明对于普通方法,如果是不同的对象实例锁是不起作用的

线程1开始执行
线程2开始执行
线程2执行完毕
线程1执行完毕

我们把上面的代码修改一下,改为同一个实例

public class SynchronizedTest {public synchronized void test(String name){System.out.println(name+"开始执行");try {Thread.sleep(2000);}catch (Exception e){}System.out.println(name+"执行完毕");}public static void main(String[] args) throws  Exception {SynchronizedTest t=new SynchronizedTest();new Thread(new Runnable() {@Overridepublic void run() {t.test("线程1");}}).start();new Thread(new Runnable() {@Overridepublic void run() {t.test("线程2");}}).start();}
}

 打印结果如下。从打印结果可以看出同一个对象实例的时候,第二个线程只有等到第一个线程执行完成后才开始执行。

线程1开始执行
线程1执行完毕
线程2开始执行
线程2执行完毕

  2.对于静态同步方法,锁的是当前类的Class对象。

public class SynchronizedTest {public synchronized static void test(String name){System.out.println(name+"开始执行");try {Thread.sleep(2000);}catch (Exception e){}System.out.println(name+"执行完毕");}public static void main(String[] args) throws  Exception {new Thread(new Runnable() {@Overridepublic void run() {SynchronizedTest.test("线程1");}}).start();new Thread(new Runnable() {@Overridepublic void run() {SynchronizedTest.test("线程2");}}).start();}
}

 打印结果如下。第一个线程执行完成后才开始执行第二个线程。

线程1开始执行
线程1执行完毕
线程2开始执行
线程2执行完毕

  3.对于同步方法快,锁的是synchonized括号里配置的对象。

public class SynchronizedTest {public  void test(String name){Object o=new Object();synchronized(o.getClass()){System.out.println(name+"开始执行");try {Thread.sleep(2000);}catch (InterruptedException e){e.printStackTrace();}System.out.println(name+"执行完毕");}}public static void main(String[] args) throws  Exception {SynchronizedTest t=new SynchronizedTest();new Thread(new Runnable() {@Overridepublic void run() {t.test("线程1");}}).start();SynchronizedTest t1=new SynchronizedTest();new Thread(new Runnable() {@Overridepublic void run() {t1.test("线程2");}}).start();}
}

打印结果如下,第一个线程执行完成后才开始执行第二个线程。

线程1开始执行
线程1执行完毕
线程2开始执行
线程2执行完毕

4、spring常用注解

 

 

 

 

5、spring事务的传播机制和隔离级别

spring事务的传播级别:


PROPAGATION_REQUIRED:Spring的默认传播级别,如果上下文中存在事务则加入当前事务,如果不存在事务则新建事务执行。
PROPAGATION_SUPPORTS:如果上下文中存在事务则加入当前事务,如果没有事务则以非事务方式执行。
PROPAGATION_MANDATORY:该传播级别要求上下文中必须存在事务,否则抛出异常。
PROPAGATION_REQUIRES_NEW:该传播级别每次执行都会创建新事务,并同时将上下文中的事务挂起,执行完当前线程后再恢复上下文中事务。(子事务的执行结果不影响父事务的执行和回滚)
PROPAGATION_NOT_SUPPORTED:当上下文中有事务则挂起当前事务,执行完当前逻辑后再恢复上下文事务。(降低事务大小,将非核心的执行逻辑包裹执行。)
PROPAGATION_NEVER:该传播级别要求上下文中不能存在事务,否则抛出异常。
PROPAGATION_NESTED:嵌套事务,如果上下文中存在事务则嵌套执行,如果不存在则新建事务。(save point概念)

事务隔离级别:
 

脏读:读取到了别的事务回滚前的数据,例如B事务修改数据库X,在未提交前A事务读取了X的值,而B事务发生了回滚。
不可重复读:一个事务在两次读取同一个数据的值不一致。例如A事务读取X,在中间过程中B事务修改了X的值,事务A再次读取X时值发生了改变。
幻读:查询得到的数据条数发生了改变,例如A事务搜索数据时有10条数据,在这时B事务插入了一条数据,A事务再搜索时发现数据有11条了。
数据隔离级别
read-uncommitted:未提交读(脏读、不可重复读、幻读)
read-committed:已提交读(不可重复读、幻读),大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”。
repeatable-read:可重复读(幻读),保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。
serializable:串行化最严格的级别,事务串行执行,资源消耗最大

Spring事务传播和隔离级别配置


@Transactional(propagation=Propagation.REQUIRED,rollbackFor=Exception.class,timeout=1,isolation=Isolation.DEFAULT)

事务的传播性:@Transactional(propagation=Propagation.REQUIRED) 如果有事务, 那么加入事务, 没有的话新建一个(默认情况下)
事务的超时性:@Transactional(timeout=30) //默认是30秒
事务的隔离级别:@Transactional(isolation = Isolation.READ_UNCOMMITTED)
回滚指定异常类:@Transactional(rollbackFor={RuntimeException.class,
Exception.class})
只读:@Transactional(readOnly=true)该属性用于设置当前事务是否为只读事务,设置为true表示只读

6、常用的git命令

远程仓库中clone代码到本地:git clone https://github.com/MatchlessHeroVIP/ssmtest.git

新增文件的命令:git add file或者git add .

提交文件的命令:git commit –m或者git commit –a

本地仓库提交到远程仓库:git push

查看工作区状况:git status –s

拉取合并远程分支的操作:git fetch/git merge或者git pull

查看提交记录命令:git reflog

切换到主分支: git checkout master


 

 7、说一说你对IOC、AOP的理解

具体的看前面的IOC、AOP笔记即可

 

相关内容

热门资讯

猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...