Java基础题整理

  1.  Java并发:彻底理解ThreadLocal
  2.  Java并发:Synchronized原理和优化
  3.  Java并发:java线程池详解
  4.  Java并发:Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
  5.  Java并发:Java中锁的分类
  6.  Java并发:Java中CAS详解
  7.  Java并发:CopyOnWriteArrayList实现原理及源码分析
  8.  Java基础:Java容器之HashMap
  9. Java基础: hashmap详解
  10.  Java并发:ConcurrentHashMap解读
  11. Java基础:JAVA Hashmap的死循环及Java8的修复
  12.  Java并发:BlockingQueue解读
  13.  Java并发:AtomicInteger源码分析——基于CAS的乐观锁实现
  14.  Java基础:值传递和引用传递
  15.  Java基础:强引用、软引用、弱引用、虚引用
  16.  Java基础:Java容器之ArrayList
  17.  Java基础:java中HashSet详解
  18.  Java基础:JAVA中BitSet使用详解
  19.   Java基础:Java容器之LinkedList
  20.  Java基础:java线程状态
  21.  Java基础:Java线程基础
  22.  Java基础:攻破JAVA NIO技术壁垒2
  23.  Java基础:攻破JAVA NIO技术壁垒1
  24.  Java基础:Java IO流学习总结
  25.  Java基础:面向接口编程详解
  26.  Java基础:Java对象初始化过程
  27.  Java基础:Java finally语句到底是在return之前还是之后执行?
  28.  Java基础:Java基础:Java的反射机制
  29.  Java基础:int与Integer区别
  30.  Java基础:java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一
  31.  Java基础:Java中重载与重写的区别
  32.  Java基础:Java 内部类和静态内部类的区别
  33.  Java基础:Java 中的 ==, equals 与 hashCode 的区别与联系
  34.  Java基础:Java抽象类与接口的区别
  35.  Java基础:谈谈final、finally、finalize的区别
  36.  spring cloud config将配置存储在数据库中
  37.  Java基础:面向对象六大原则
  38.  Java基础:Java面向对象的特征
  39.  Java基础:volatile 关键字:保证变量的内存可见性,禁止指令重排
  40.  Java基础:指令重排
  41.  Java基础:ReentrantLock

 

  1.  通俗易懂: 内存溢出和内存泄露
  2. SQL处理报表,列转行的问题
  3. 集合Collection
  4. 实现分布式锁
  5. 实现分布式事务
  6. 反射
  7. java中的23种设计模式
  8. jvm垃圾回收算法
  9. jvm堆内存模型及gc(垃圾回收)原理
  10. jvm常用的垃圾回收器
  11. jvm内存溢出OOM及解决方案
  12. 主从数据库原理
  13. mysql的搜索引擎和索引
  14. mysql索引讲解
  15. mysql数据库隔离级别
  16. mysql锁机制-记录锁、间隙锁、临键锁
  17. 类加载器:
  18. 线程池
  19. CPU密集型、IO密集型应用如何分配线程池大小
  20. JDK1.8新特性
  21. redis数据类型及应用场景
  22. redis持久化策略、resp协议介绍
  23. kafka面试题
  24. kafka如何保证数据不丢失
  25. java中引用对象作为map的key,要注意的问题
  26. spring如何解决循环依赖的问题
  27. 用redis缓存如何解决数据滞后的问题
  28. 缓存穿透、缓存雪崩、缓存击穿(热点key问题)
  29. Mybatis的三级缓存
  30. 数据计算的时空复杂度
  31. spring启动过程及原理
  32. Java阻塞队列

 

Java散列(哈希)表原理及解决hash碰撞的办法

# 解决散列表的hash碰撞,总结:
1. 多重哈希:(如布隆过滤器)散列数组存储的是0,1,hash碰撞后无法判断值key是否一致,所以采用多重hash尽量防止碰撞
2. 开放寻址法:散列数组存储的是Entry,当hash碰撞后可以判断Entry中key是否冲突,不冲突则(hash+1)/array.lenth,继续判断直到找到冲突的Entry或空余的槽位。
3. 链地址法:采用哈希数组+链表结构(数组中每位存储的还是Entry,Entry.next指向下个Entry,形成链表)。发生hash碰撞后,通过Entry.next扫描当前链表。Hash函数尽量保证较少的碰撞和较平均的链表分布,能提高其添加和查找的效率。

transactional 嵌套、事务传播行为详解

NESTED和REQUIRED修饰的内部方法都属于外围方法事务,如果外围方法抛出异常,这两种方法的事务都会被回滚。但是REQUIRED是加入外围方法事务,所以和外围事务同属于一个事务,一旦REQUIRED事务抛出异常被回滚,外围方法事务也将被回滚。
而NESTED是外围方法的子事务,有单独的保存点,所以NESTED方法抛出异常被回滚,不会影响到外围方法的事务。

NESTED和REQUIRES_NEW都可以做到内部方法事务回滚而不影响外围方法事务。但是因为NESTED是嵌套事务,所以外围方法回滚之后,作为外围方法事务的子事务也会被回滚。
而REQUIRES_NEW是通过开启新的事务实现的,内部事务和外围事务是两个事务,外围事务回滚不会影响内部事务

解决缓存穿透,布隆过滤器原理解析

# 总结
BloomFilter具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一个成员。如果检测结果为是,该元素不一定在集合中;但如果检测结果为否,该元素一定不在集合中。因此Bloom filter具有100%的召回率。
BloomFilter是一个长度为长度为n的字节数组byte[n],最大长度为int的长度。每位都初始0,现有3个hash函数,可将字符串计算成int。我们将表中某个column全部获取到,通过这3个hash计算出所有整数,并将byte中这些下标对应的值改成1,即这些column已经全部存到BloomFileter中。
现过来一个key=“DJ0023045”,通过3个hash分别得出10,100,1000这3个数字,然后获取byte[10],byte[100],byte[1000]所在的数字。我们就能判断这个key在BloomFilter中是否存在。
但凡有一个结果是0,都说明这个key没在布隆过滤器里存储过。如果全部得到的是1,那说明可能是存储过,存在一定的误判几率。
因为有可能获取到的这3个数,分别是其他3个key存储在布隆过滤器的,恰巧被该key全部命中。由于hash函数输出的是int类型(最大长度2147483647),存在一定几率的hash碰撞。
 
# 静态代理总结
1. 静态代理要求目标类和代理类都要实现同一接口
2. 静态代理只代理到方法级别
3. 代码量大,目标类有改动,代理类也要调整
# 动态代理总结
1. JDK代理还是会要求目标类实现一个接口,如果没实现接口无法代理
2. 动态代理是代理到类级别,代码量小

ThreadLocal的使用以及坑

# 应用场景
Spring的事务管理器通过AOP切入业务代码,在进入业务代码前,会依据相应的事务管理器提取出相应的事务对象,假如事务管理器是DataSourceTransactionManager,就会从DataSource中获取一个连接对象,通过一定的包装后将其保存在ThreadLocal中。
而且Spring也将DataSource进行了包装,重写了当中的getConnection()方法,或者说该方法返回的连接将由Spring来控制,这样Spring就能让线程内多次获取到的Connection对象是同一个。为什么要放在ThreadLocal里面呢?由于Spring在AOP后并不能向应用程序传递參数。
应用程序的每一个业务代码是事先定义好的,Spring并不会要求在业务代码的入口參数中必须编写Connection的入口參数。此时Spring选择了ThreadLocal,通过它保证连接对象始终在线程内部,不论什么时候都能拿到,此时Spring很清楚什么时候回收这个连接,也就是很清楚什么时候从ThreadLocal中删除这个元素
# 要避免的坑
当使用不当时,导致使用者不知道它的作用域范围。
大家可能觉得线程结束后ThreadLocal应该就回收了。假设线程真的注销了确实是这种,可是事实有可能并不是如此。比如在线程池中对线程管理都是採用线程复用的方法(Web容器通常也会採用线程池)。在线程池中线程非常难结束甚至于永远不会结束。
这将意味着线程持续的时间将不可预測,甚至与JVM的生命周期一致,这就很容易导致内存泄露。在使用时要明确ThreadLocal最难以捉摸的是“不知道哪里是源头”,仅仅有知道了源头才干控制结束的部分。或者说我们从设计的角度要让ThreadLocal的set、remove有始有终,通常在外部调用的代码中使用finally来remove数据。
# 造成的后果
1.线程池中线程还在,所以threadlocal也没有销毁,导致内存泄露
2.线程池中该线程在重复使用,可能获取到上一次执行时存储的数据。导致数据不准确

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值