求职刷题神器

funit.cn

讨论区 > 求职面经 > 北京用友软件有限公司Java开发岗位面经,结果未知

北京用友软件有限公司Java开发岗位面经,结果未知

淮南刘德华
发布于2021-06-24 17:48:24 243浏览

面试公司:北京用友软件有限公司
面试岗位:java开发
面试难度:较难
面试结果:待定

面试问题:
1.如何利用索引提升查询速率(任何优化一个慢查询);
2.MyBatis 执行一个 Select 查询的流程?
3.线程volatile 关键字原理;
4.Synchronized 和 ReentraintLock 区别;
5.线程通信方式有哪些;
6.双向链表如何判断有交叉?如何找到交叉点?
7.Hash 可以做索引吗?为什么 InnoDB 不使用 Hash 索引?
8.怎么判断一个查询走没走索引,like 走索引吗?
9.Left Join 是怎么执行的?
10.如何判断一个对象是否要被回收?
11.ConcurrentHashMap 怎么实现线程安全的?
12.HashMap为什么不是线程安全的,并发情况下会有什么问题?
本文首次发布于趣IT ,转载请注明出处,谢谢合作

北京用友软件有限公司Java开发岗位面经,结果未知

全部评论11
  1. iter5850203138 2021-06-24 22:33:24
    ### 1.如何利用索引提升查询速率(任何优化一个慢查询)
    
    当数据量较大时,搜索某个字段的值,如果不加索引,势必需要在全表范围内进行扫描,查询速度就会受限于磁盘 I/O,如果为该列建立索引,就会对该列字段进行排序,以 B+ 树方式存储数据(千万的数据量 B+ 树的高度也是 3-4 层),仅需少量几次 I/O,就可以轻松找到所需数据。
    4 全部回复(1) 举报
    • 淮南刘德华 2021-06-25 14:32:12
        学习了
      0 举报
  2. iter5850203138 2021-06-24 22:33:35
    ### 2.MyBatis 执行一个 Select 查询的流程?
    
    * 由 SqlSession 的实现获取到映射的语句对象(MappedStatement),从 xml 或注解中来
    * 由 executor (有多种实现,默认实现底层是用了 PreparedStatement)执行语句对象
    * 执行前需要由 ParameterHandler 和 TypeHandler 对参数做处理包括类型转换
    * 由 StatementHandler 执行查询
    * 查询结果由 ResultSetHandler 进行处理,根据 ResultMap 对结果进行映射,这个过程中还会用到 TypeHandler 对结果进行类型转换
    * 返回结果
    3 举报
  3. iter5850203138 2021-06-24 22:33:51
    ### 3.线程volatile 关键字原理
    
    volatile 修饰的变量,可以保证其在多线程内的可见性和有序性。
    
    * 可见性的意思是,让线程 a 对该变量的修改被线程 b 观察到,也就是读到最新的值,如果变量未用 volatile 修饰,则由于编译器、缓存等优化,其它线程读取到的可能是旧值,从而引发错误
    * 有序性的意思是,由于缓存、cpu 指令重排等优化机制的存在,可能会现有指令的执行顺序重新进行调整,这在单线程下是没有问题的,但多线程下也会有几率造成错误的结果
    * volatile 的原理是在变量的读写前后插入了内存屏障,来阻止缓存、cpu 对指令的重排,保证有序性;即时编译器也会避免对 volatile 修饰的变量进行指令优化,从而避免了可见性问题
    3 举报
  4. iter5850203138 2021-06-24 22:34:09
    ### 4.Synchronized 和 ReentraintLock 区别
    
    * synchronized 是内置语法,它是采用了操作系统提供的 Monitor 作为锁,保证访问变量时的原子性、有序性、可见性。
    * 加锁时线程首先根据对象头(包含了锁地址)找到 Monitor 锁,检查该锁是否已被占用,若没有则加锁成功;否则进入 Monitor 的阻塞队列等待,当持锁线程释放锁时,会唤醒阻塞队列中的线程进行下一轮的锁竞争
    * 最早的 synchronized 语法仅支持 Monitor 锁,在 java 6 以后,还对它的底层实现进行了轻量级锁、偏向锁的优化,提升没有竞争时的加锁性能
    * ReentrantLock 是 java 5 加入的一个线程工具类,作用与 synchronized 类似,可以理解为用 java 语言实现了 synchronized 的功能(synchronized 的执行是在 jvm 层面,属于 c++ 代码),当然它也比 synchronized 多出了原本没有的功能,例如
      * 公平锁
      * 可中断特性
      * 可尝试加锁
    * 在竞争激烈的情况下 ReentrantLock 的性能更优,但低竞争情况下 synchronized 有优化并不差;ReentrantLock  需要注意用 finally 保证锁的正确释放,synchronized 在语法层面保证锁的释放;如果需要公平锁、可中断、可尝试等特性,需要使用 ReentrantLock
    3 全部回复(1) 举报
    • 淮南刘德华 2021-06-25 14:34:01
      当时回答的没有你这么全      
      0 举报
  5. iter5850203138 2021-06-24 22:34:31
    ### 5.线程通信方式有哪些
    
    * synchronized 可以使用 wait,notify 方式实现通信
    * ReentrantLock  可以使用条件变量实现通信
    * 还可以使用更高级的线程工具类进行通信,例如
      * 阻塞队列
      * CountDownLatch
      * CompletableFuture
      * ...
    3 举报
  6. iter5850203138 2021-06-24 22:34:43
    ### 6.双向链表如何判断有交叉?如何找到交叉点?
    
    明确一点,如果两个链表有交叉,则从交叉点开始,后面的节点都会重叠
    
    * 判断链表 a 中的所有节点是否在链表 b 中,显然这种方法性能太低
    * 对链表 a 中的节点建立 hash 表,然后链表 b 中每个节点查表,缺点是需要增加额外存储空间
    * 将两个链表连在一起,判断是否有环(可以用快慢指针法)
    * 如果两个链表有交叉,则交叉节点之后一定会有共有节点,遍历第一个链表,记住最后一个节点,再遍历第二个链表到最后一个节点时与之前记住的比较,如果相同则相交
    * 判断出相交后,两个链表同时从最后节点倒着向回遍历(题目说是双向链表),第一个不同的节点之前的即为相交节点
    3 举报
  7. iter5850203138 2021-06-24 22:34:55
    ### 7.Hash 可以做索引吗?为什么 InnoDB 不使用 Hash 索引?
    
    * 可以做 hash 索引,但 hash 索引只能做等值比较,如果需要范围比较就不适用了
    
    ### 8.怎么判断一个查询走没走索引,like 走索引吗?
    
    * 可以通过 explain 查询分析器观察 sql 是否走了索引
    * like 查询时如果条件满足最左前缀,例如 like 'a%' 是会走索引的
    3 举报
  8. iter5850203138 2021-06-24 22:35:19
    ### 9.Left Join 是怎么执行的?
    
    * 左外连接会选择左表 L 作为驱动表,如果被驱动表 R 连接字段上建有索引,那么遍历表 L 中每一条记录(全表扫描),去 R 中根据连接条件匹配(索引扫描),找到了则连成一行,这种形式称为 Index Nested-Loop Join
    * 如果被驱动表 R 的连接字段上没有索引,每连接一条记录,R 也会进行一次全表扫描,这种形式称为 Simple Nested-Loop Join,显然性能太低,MySQL 并不会采用这种算法
    * 把表 L 的数据读入 join_buffer 中,即把表 L 中数据放入了内存与 R 进行连接,R 仍然做全表扫描,如果 join_buffer 不够大,会分块将 L 的数据读入,因此这种形式也称为 Block Nested-Loop Join
    3 举报
  9. iter5850203138 2021-06-24 22:35:33
    ### 10.如何判断一个对象是否要被回收?
    
    * JVM 使用了可达性分析算法来判断一个对象能否被回收,首先找到 GC root 对象(当前栈帧中还存在的对象、静态变量、常量等)即那些确定不能回收的对象,然后沿着这些对象的引用链进行查找,如果在这个引用链上,表示还在使用不能回收,否则可以回收
    2 举报
  10. iter5850203138 2021-06-24 22:35:52
    ### 11.ConcurrentHashMap 怎么实现线程安全的?
    
    * 以每个链表为单位,链表头节点作为锁,减少了锁的粒度,提升了并发性
    * 读操作不需加锁,仅需利用 volatile 保证可见性
    * 写操作在创建数组、和向数组添加头节点时,利用 cas 保证原子性,追加、更新节点时用 synchronized 保证原子性
    * 扩容时也以链表为单位加锁,扩容时,其它竞争线程也不会闲着,可以帮忙扩容
    * 统计个数时用类似 LongAdder 的方案分成多个累加单元进行 cas 累加计数,减少 cas 竞争
    3 举报
  11. iter5850203138 2021-06-24 22:36:12
    ### 12.HashMap为什么不是线程安全的,并发情况下会有什么问题?
    
    * HashMap 中调用 put 等方法时,并不是原子操作,例如线程 a 将一个 Node 存入数组时,线程 b 也将另一个 Node 存入数组的相同索引,这样它们的结果就可能相互覆盖
    * 1.8 和 1.7 的 HashMap 都会存在多线程并发数据相互覆盖、数据错乱的问题
    * 1.7 的 HashMap 还会在多线程并发扩容时产生死链问题
    3 全部回复(2) 举报
    • 富士山上尢 2021-06-25 11:08:37
      大佬,我膜拜了!
      1 举报
    • 诡异 2021-06-25 11:15:12
      这是潜水的大牛
      0 举报

还可以上传7

表情
  • 快速扫码进群
    加入职友圈
下一步
知道了