2024年最全百度面试总结_为什么 untreeify_threshold 定为6 (1),Golang教程零基础入门

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

mybatis建立数据库连接执行SQL过程:

  1. 通过 Resources 工具类读取 mybatis-config.xml, 存入 Reader;
  2. SqlSessionFactoryBuilder使用上一步获得的reader创建SqlSessionFactory对象;(建造者模式)
  3. 通过 sqlSessionFactory 对象获得SqlSession;(工厂模式)
  4. SqlSession对象通过selectList方法找到对应的“selectAll”语句, 执行SQL查询。
  5. 底层通过 JDBC 查询后获得ResultSet, 对每一条记录, 根据resultMap的映射结果映射到Student中, 返回List。
  6. 最后记得关闭 SqlSession。

Mybatis中,Resources工具类读取mybatis-config.xml配置文件。拿到SqlSession对象之后,可以通过SqlSession拿到Mapper对象(DAO层的实体对象的映射),然后通过Mapper对象执行Sql语句最后放到ResultSet结果集中。执行Sql语句时#{}是属于静态SQL,通过预编译后把#{}的语句可以防止Sql注入, 是属于动态 S Q L 在运行期才会把 S Q L 中的 {}是属于动态SQL在运行期才会把SQL中的 是属于动态SQL在运行期才会把SQL中的{}进行解析。

MapperBuilderAssistant类中把MappedStatement放到全局配置文件Configuration里,MappedStatement用到StrictMap(继承了HashMap重写了put方法,不能存重复的key),再解析注解上的内容。

Mybatis-Spring工具包通过@MapperScanner扫描包路径下的Mapper对象,扫描注册类MapperScannerRegistrar里的registerBeanDefinitions方法的ClassPathMapperScanner获得Spring的注册器Register,ClassPathMapperScanner类通过doScan方法(父类ClassPathBeanDefinitionScanner的doScan方法)实现扫描并注册到Spring IOC容器中。

3、redis除了做分布式锁、缓存以外还能做什么?redis做排行榜怎么做?

比如登陆验证等。排行榜使用有序集合Sorted Set。

  1. ZADD:添加or更新成员分数
  2. ZREVRANK:获取成员当前的排名
  3. ZSCORE:获取用户排名

4、线程安全的集合有哪些?AQS是什么?

线程安全的集合实现synchronizedCollection,有List、Map、Set。

抽象队列同步器AQS(AbstractQueuedSynchronizer)定义两种资源共享方式:Exclusive(独占,只有一个线程能执行,如ReentrantLock)和Share(共享,多个线程可同时执行,如Semaphore/CountDownLatch)。

如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并将共享资源设置为锁定状态,如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是用CLH队列锁实现的,即将暂时获取不到锁的线程加入到队列中。

5、什么时候用可重入锁?

可重入锁指的是在一个线程中可以多次获取同一把锁。(独占式)

重入进一步提升了加锁行为的封装性,因而简化了面向对象并发代码的开发。在以下程序中,子类改写了父类的 synchronized 方法,然后调用父类中的方法,此时如果内置锁不是可重入的,那么这段代码将产生死锁。由于 Widget 和 LoggingWidget 中 doSomething 方法都是 synchronized 方法,因此每个每个 doSomething 方法在执行前都会获取 Widget 上的锁。然而如果内置锁不是可重入的,那么调用 super.doSomething( )时无法获得 Widget 上的锁,因为这个锁已经被持有,从而线程将永远停顿下去,等待一个永远也无法获得的锁。重入则避免了这种死锁情况的发生

public class Widget{
    public synchronized void doSomething(){
        ........
    }
}

public class LoggingWidget extends Widget{
    public synchronized void doSomething(){
        super.doSomething();
    }
}


6、分布式锁中如果超过了过期时间30s任务没执行完怎么办?

Redis有watch dog,一旦加锁成功就会启动一个watch dog,他是一个后台线程,会每隔10秒检查一下,如果客户端 1 还持有锁 key,那么就会不断的延长锁 key 的生存时间。

7、Hashmap什么时候扩容?

如果新增节点之后,所在链表的元素个数达到了阈值 8,则会调用treeifyBin方法把链表转换成红黑树,不过在结构转换之前,会对数组长度进行判断。

如果lo链表的元素个数小于等于UNTREEIFY_THRESHOLD,默认为6,则通过untreeify方法把树节点链表转化成普通节点链表

8、ConcurrentHashMap为什么线程安全?

ConcurrentHashMap实现ConcurrentMap接口,ConcurrentHashMap是由一个Segment数组和多个HashEntry数组组成。

其实就是将HashMap分为多个小HashMap,每个Segment元素维护一个小HashMap,目的是锁分离,本来实现同步,直接可以是对整个HashMap加锁,但是加锁粒度太大,影响并发性能,所以变换成此结构,仅仅对Segment元素加锁,降低锁粒度,提高并发性能。

ConcurrentHashMap是数组+链表,或者数组+红黑树结构,并发控制使用Synchronized关键字和CAS操作

参考:阿里面试题:ConcurrentHashMap为什么是线程安全的?_zycxnanwang的博客-CSDN博客_concurrenthashmap为什么线程安全

9、ConcurrentHashMap(JDK1.8)为什么要使用synchronized而不是可重入锁?

ConcurrentHashMap的treeifyBin方法、putVal方法、replaceNode方法、clear方法、computeIfAbsent方法、merge方法、transfer方法都是对Node节点进行加锁(使用synchronized关键字)。

为什么是synchronized,而不是可重入锁 :

  1. 减少内存开销 
    假设使用可重入锁来获得同步支持,那么每个节点都需要通过继承AQS来获得同步支持。但并不是每个节点都需要获得同步支持的,只有链表的头节点(红黑树的根节点)需要同步,这无疑带来了巨大内存浪费。
  2. 获得JVM的支持 
    可重入锁毕竟是API这个级别的,后续的性能优化空间很小。 
    synchronized则是JVM直接支持的,JVM能够在运行时作出相应的优化措施:锁粗化、锁消除、锁自旋等等。这就使得synchronized能够随着JDK版本的升级而不改动代码的前提下获得性能上的提升。

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

体系化!**

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值