首页
薅羊毛
工具
留言板
更多
关于
Search
1
青龙挂某手极速版,某条极速版,饿了么,美团脚本!
8,605 阅读
2
IOS微信无需越狱导入自己喜欢的语音包!
5,191 阅读
3
IOS免越狱自签教程!
5,026 阅读
4
删除mysql表卡死 , 打不开,一直转圈圈
2,423 阅读
5
Java中批量修改List集合中某个字段的两种方法
2,093 阅读
JAVA
面试
前端
Python
易语言
其他
登录
Search
尼采
累计撰写
72
篇文章
累计收到
19
条评论
首页
栏目
JAVA
面试
前端
Python
易语言
其他
页面
薅羊毛
工具
留言板
关于
搜索到
4
篇与
面试
的结果
2023-02-25
引用类型有哪些?有什么区别?
四种引用类型:在 JDK.1.2 之后,Java 对引用的概念进行了扩充,将引用分为了:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)4 种,这 4 种引用的强度依次减弱。StrongReference > SoftReference > WeakReference > PhantomReference强引用:Java中默认声明的就是强引用,只要强引用存在,垃圾回收器将永远不会回收被引用的对象,哪怕内存不足时,JVM也会直接抛出OutOfMemoryError,不会去回收。如果想中断强引用与对象之间的联系,可以显示的将强引用赋值为null,这样一来,JVM就可以适时的回收对象了。软引用:软引用是用来描述一些非必需但仍有用的对象。在内存足够的时候,软引用对象不会被回收,只有在内存不足时,系统则会回收软引用对象,如果回收了软引用对象之后仍然没有足够的内存,才会抛出内存溢出异常。这种特性常常被用来实现缓存技术,比如网页缓存,图片缓存等。弱引用:弱引用的引用强度比软引用要更弱一些,无论内存是否足够,只要 JVM 开始进行垃圾回收,那些被弱引用关联的对象都会被回收。在 JDK1.2 之后,用 java.lang.ref.WeakReference来表示弱引用。虚引用:虚引用是最弱的一种引用关系,如果一个对象仅持有虚引用,那么它就和没有任何引用一样,它随时可能会被回收,在 JDK1.2 之后,用 PhantomReference 类来表示,通过查看这个类的源码,发现它只有一个构造函数和一个 get() 方法,而且它的 get() 方法仅仅是返回一个null,也就是说将永远无法通过虚引用来获取对象,虚引用必须要和 ReferenceQueue 引用队列一起使用。引用队列(ReferenceQueue):引用队列可以与软引用、弱引用以及虚引用一起配合使用,当垃圾回收器准备回收一个对象时,如果发现它还有引用,那么就会在回收对象之前,把这个引用加入到与之关联的引用队列中去。程序可以通过判断引用队列中是否已经加入了引用,来判断被引用的对象是否将要被垃圾回收,这样就可以在对象被回收之前采取一些必要的措施。
2023年02月25日
117 阅读
1 评论
4 点赞
2023-02-23
事务的四种隔离级别与七种传播方式
一.事务的隔离级别:{card-describe title=" 脏读: "} 所谓的脏读,其实就是读到了别的事务回滚前的脏数据。比如事务B执行过程中修改了数据X,在未提交前,事务A读取了X,而事务B却回滚了,这样事务A就形成了脏读。也就是说,当前事务读到的数据是别的事务想要修改成为的但是没有修改成功的数据。{/card-describe}{card-describe title=" 不可重复读: "} 事务A首先读取了一条数据,然后执行逻辑的时候,事务B将这条数据改变了,然后事务A再次读取的时候,发现数据不匹配了,就是所谓的不可重复读了。也就是说,当前事务先进行了一次数据读取,然后再次读取到的数据是别的事务修改成功的数据,导致两次读取到的数据不匹配,也就照应了不可重复读的语义。{/card-describe}{card-describe title=" 幻读: "} 事务A首先根据条件索引得到N条数据,然后事务B改变了这N条数据之外的M条或者增添了M条符合事务A搜索条件的数据,导致事务A再次搜索发现有N+M条数据了,就产生了幻读。也就是说,当前事务读第一次取到的数据比后来读取到数据条目不一致。{/card-describe}1.读未提交 (Read uncommitted)就是一个事务可以读取到另一个未提交事务的数据。例:老板要给员工发工资,员工的工资是1万/月。但是发工资时老板不小心按错了数字,按成1.1万/月,该钱已经打到员工的卡上,但是事务还没有提交,就在这时,员工去查看自己这个月的工资,发现比往常多了1千元,以为涨工资了非常高兴。但是老板及时发现了不对,马上回滚差点就提交了的事务,将数字改成1万再提交。分析:员工这个月的工资还是1万,但是员工看到的是1.1万。他看到的是老板还没提交事务时的数据,这就是脏读。2.读已提交 (Read committed)就是一个事务要等另一个事务提交后才能读取数据。例:员工拿着信用卡去享受生活(卡里当然是只有1万),当他买单时(员工事务开启),收费系统事先检测到他的卡里有1万,就在这个时候!!员工的妻子要把钱全部转出充当家用,并提交。当收费系统准备扣款时,再检测卡里的金额,发现已经没钱了(第二次检测金额当然要等待妻子转出金额事务提交完)。员工就会很郁闷,明明卡里是有钱的…分析:这就是读已提交,若有事务对数据进行更新(UPDATE)操作时,读操作事务要等待这个更新操作事务提交后才能读取数据,可以解决脏读问题。但在这个事例中,出现了一个事务范围内两个相同的查询却返回了不同数据,这就是不可重复读。3.可重复读 (Repeatable read) 就是在开始读取数据(事务开启)时,不再允许修改操作。例:员工拿着信用卡去享受生活(卡里当然是只有1万),当他买单时(事务开启,不允许其他事务的UPDATE修改操作),收费系统事先检测到他的卡里有1万。这个时候他的妻子不能转出金额了,接下来收费系统就可以扣款了。分析:可重复读可以解决不可重复读问题。写到这里,应该明白的一点就是,不可重复读对应的是修改,即UPDATE操作。但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT操作,而不是UPDATE操作。什么时候会出现幻读? 例:程序员某一天去消费,花了2千元,然后他的妻子去查看他今天的消费记录(全表扫描FTS,妻子事务开启),看到确实是花了2千元,就在这个时候,程序员花了1万买了一部电脑,即新增INSERT了一条消费记录,并提交。当妻子打印程序员的消费记录清单时(妻子事务提交),发现花了1.2万元,似乎出现了幻觉,这就是幻读。那怎么解决幻读问题? 1.通过对select操作手动加行X锁(SELECT … FOR UPDATE )。原因是InnoDB中行锁锁定的是索引,纵然当前记录不存在,当前事务也会获得一把记录锁(记录存在就加行X锁,不存在就加next-key lock间隙X锁),这样其他事务则无法插入此索引的记录,杜绝幻读。 2.进一步提升隔离级别为SERIALIZABLE4.可串行化 Serializable 是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读,但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。四种隔离级别可能导致的问题: 1.读未提交 :事务中的修改,即使没有提交,其他事务也可以看得到,会导致“脏读”、“幻读”和“不可重复读取”。 2.读已提交:大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”,但不能避免“幻读”和“不可重复读取”。该级别适用于大多数系统。 3.可重复读:保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”的情况,但不能避免“幻读”,但是带来了更多的性能损失。 4.可串行化:最严格的级别,事务串行执行,资源消耗最大。事务的七种传播方式:REQUIRED(默认):支持使用当前事务,如果当前事务不存在,创建一个新事务。SUPPORTS:支持使用当前事务,如果当前事务不存在,则不使用事务。MANDATORY:中文翻译为强制,支持使用当前事务,如果当前事务不存在,则抛出Exception。REQUIRES_NEW:创建一个新事务,如果当前事务存在,把当前事务挂起。NOT_SUPPORTED:无事务执行,如果当前事务存在,把当前事务挂起。NEVER:无事务执行,如果当前有事务则抛出Exception。NESTED:嵌套事务,如果当前事务存在,那么在嵌套的事务中执行。如果当前事务不存在,则表现跟REQUIRED一样。格式:@Transactional(propagation = Propagation.REQUIRES_NEW)Spring支持编程式事务管理以及声明式事务管理两种方式编程式事务管理编程式事务管理是侵入性事务管理,使用TransactionTemplate或者直接使用PlatformTransactionManager,对于编程式事务管理,Spring推荐使用TransactionTemplate。声明式事务管理声明式事务管理建立在AOP之上,其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,执行完目标方法之后根据执行的情况提交或者回滚。编程式事务每次实现都要单独实现,但业务量大功能复杂时,使用编程式事务无疑是痛苦的,而声明式事务不同,声明式事务属于无侵入式,不会影响业务逻辑的实现,只需要在配置文件中做相关的事务规则声明或者通过注解的方式,便可以将事务规则应用到业务逻辑中。显然声明式事务管理要优于编程式事务管理,这正是Spring倡导的非侵入式的编程方式。唯一不足的地方就是声明式事务管理的粒度是方法级别,而编程式事务管理是可以到代码块的,但是可以通过提取方法的方式完成声明式事务管理的配置。
2023年02月23日
128 阅读
0 评论
2 点赞
2023-01-07
CAS的原理及其带来的问题!
CAS原理:CAS全称Compare and Swap,比较并交换,主要是通过处理器的指令来保证操作的原子性.CAS的思想比较简单,主要涉及到三个值:当前内存值V预期值(旧的内存值)A即将更新的内存值B当执行CAS指令时,只有当内存值V等于预期值A时,才会将内存值V修改为更新值B,否则就不会执行更新操作。CAS主要使用在一些需要上锁的场景充当乐观锁解决方案,一般在一些简单且要上锁的操作但又不想引入锁场景,这时候来使用CAS代替锁。CAS有什么缺点:1.ABA问题: ABA问题是指有一个线程t1在进行CAS操作时,其他线程t2将变量A改成了B,然后又将其改成A,这时候t1发现A并没有改变,因此进行了交换操作,由于在交换操作进行前变量A其实是有变化的,只不过最终又修改回A了,此A非彼A,这时候进行交换操作在一些业务场景下很可能要出问题,要解决ABA问题有2种方案。 方案一: 在对变量进行操作的时候给变量加一个版本号,每次对变量操作都将版本号加1,常见在数据库的乐观锁中可见。 方案二: Java提供了相应的原子引用类AtomicStampedReference,他加入了预期标志和更新后标志两个字段,更新时不光检查值,还要检查当前的标志是否等于预期标志,全部相等的话才会更新。2.自旋带来的消耗: CAS自旋如果很长时间都不成功,这会给CPU带来很大的开销。 解决方案: 1、代码层面破坏掉for循坏,设置合适的循环次数。 2、使用JVM能支持处理器提供的pause指令来提升效率,它可以延迟流水线执行指令,避免消耗过多CPU资源。3.CAS只能单变量: 对于一个共享变量,可以使用CAS方式来保证原子操作,但是当多个共享变量时,那就无法使用CAS来保证原子性。JDK1.5开始,提供了AtomicReference类来保证引用对象之前的原子性,就可以把多个变量放在一个对象里来进行CAS操作。在JDK1.5中新增的java.util.concurrent(JUC),就是建立在CAS之上的,一般来说CAS这种乐观锁适合读多写少的场景。
2023年01月07日
155 阅读
0 评论
2 点赞
2022-07-31
Java基础面试题!
免费编程资源大全 未完待续~
2022年07月31日
143 阅读
0 评论
4 点赞