字节跳动客户端开发实习一面凉经
飞书视频面 2.22, 19:00,70mins
1. String 类的不可变性
内部的char[] 或 byte[] 的修饰符为 private final,final 使其只能指向该对象数组,private修饰 同时没有提供set、 get方法导致外部类无法访问,String类的修饰符为final,无法被其他类继承,保证了以上的机制不被破坏;
2. String类为什么要设置为不可变 (不会)
百度答案:https://blog.csdn.net/weixin_45525272/article/details/127729538
3. 给的代码场景 大意是并发一百个线程 对num加1最终的结果,以及如何优化
最开始num没有加volate,并发执行num加1操作,最坏的结果可能num=2,最好的结果num=100,num的值在[2,100];
代码优化:给num加 volate关键字, 仍然不能保证结果正确,因为volate不保证原子性; 加Synchronized关键字,且锁的是类对象才能达到线程安全。面试官继续问优化-- 答了加Lock锁
4. ReentrentLock 和 Synchronized 的区别
ReentrentLock 是基于API完成的,使用了AQS队列和CAS实现,Synchronized 是基于JVM实现的,使用Monitor对象锁,答了Synchronized 的锁优化,由Monitor对象答到对象实例化的过程,对象头中MarkWord;
5. 偏向锁的过程
根据当前获得锁对象的线程是否上一个获取对象的线程id,若相同则直接操作该共享资源,id不相同则表示有两个以上线程争抢资源,将偏向锁撤掉升级为轻量级锁
6. 自旋锁的优点缺点
自旋锁会一直占用cpu资源轮询的去尝试获取对象锁,优点是不用将线程阻塞,可以很快的响应用户请求,因为线程从阻塞到再次获取cpu执行权等待的时间长,不利于低延时;缺点是当有很多线程都在自旋状态的话会大量浪费cpu资源;所以推荐当线程数比较多的情况下将自旋锁升级为重量级锁,使用AQS队列管理线程的阻塞唤醒和唤醒后的锁分配问题;
7. 还是第3个问题的场景继续优化
答了使用线程池去创建线程,而不是在一个for循环中创建100个线程;
8. 线程池的优点,几个重要的参数,如果有多个任务同时产生,线程池的执行流程
9. 单例模式
手写了懒汉式的单例模式,写了几种优化实现,从线程不安全 优化为 在方法上加 synchronized保证线程安全但是效率差,优化到 在方法内加synchronized代码块 但效率还是比较差, 再优化到 双重判断 保证线程安全和效率,最后优化为 给对象加volate 保证其有序性;
10. ThreadLocal 的理解
key为弱引用,value为强引用,答了强软弱虚的四中引用差异
11. ThreadLocal 中key为什么要设置为弱引用,value要设置为强引用 (不会)
百度答案:https://blog.csdn.net/foxException/article/details/123496254
12. hashMap 的一系列八股
hashMap 的hash算法、 为什么数组长度始终维护为2的次幂,初始化时若设置的不是2的次幂怎么把他变为为2的次幂;
13. 进程和线程区别
答了进程、线程、协程的八股;
14. 进程为什么要设置虚拟内存
答了虚拟内存的映射,面试官不满意。。
百度答案:https://www.php20.cn/article/337
15. 项目中的 SQL 调优
从不加索引的全表扫描 ,到加了一个普通二级索引的扫描索引树,到改为联合索引使得在二级索引树中就能得到需要的字段值,避免了回表的发生;
16. MySQL 的数据结构
因为加索引的目的就是为了快速查到数据所在的位置;讲了为什么不用O(1)复杂的哈希索引,排除o(1)后,就只能用O(logN),讲了为什么不用BST、AVL、红黑树、B树的缺点,最终推出了要用B+树;对比B树讲了B+树的优点;
17. easy级的算法题 二叉树的最近公共祖先;
算法菜死了,没 a 。。。
18. 反问面试评价:基础知识比较牢固,代码能力需要加强。 寄
#我的实习求职记录##字节##双非本科如何走出求职困境##24届实习#