本人双非本科,因为之前打了两年ACM,所以没什么项目经验,也没有实习经历。秋招投了很多公司,但往往这些公司都看重项目经历,所以基本都凉凉。前段时间投了字节客户端,因为说是不看重项目经历,看重的是基础。面试过程也确实如此。问的都是计算机网络,java相关的问题。一面没什么问题就过了,到了二面问的也都是基础,我当时觉得自己答的都不错,但第二天,收到面试未通过的邮件。问了hr原因,hr说是因为我的回答都是根据网上的不准确。因为学校的问题,所以我平时学习都是自己一点一点在网上学的。说我回答不准确,为什么不在面试过程直接提出来呢?我网上学习的过程中,大多通过博客和视频,学一个知识点,我至少要在网上看十几篇的博客,对于他们的结论我能验证的都会去验证,然后自己再做总结。觉得自己真的很悲哀,那我现在要质疑自己辛辛苦苦做的总结,那么什么又是正确的说法呢。觉得自己在二面口若悬河的样子真像个傻子,希望大佬们能给我推荐一个正确的学习方式吧。
整理下面试过程,大佬们帮我看看什么地方理解有问题
面试官:介绍下HashMap
我:HashMap结构大致是一个Entry数组,每个Entry下面用链表的形式连接着一个又一个对象
HashMap1.8引入了红黑树的数据结构,因为当链表过长了就会hashMap的效率就会降低。当链表长度达到8就会变成红黑树,到6了又会退化成链表。
但其实红黑树这个结构在实际使用过程中是很难达到的,在hashmap源码中提到hashmap使用过程符合泊松分布,只有0.0000几的概率才会出现1个Entry数组下链表长度过长导致出现红黑树结构
hashmap的hash过程主要是hashcode()异或上容量-1,因为hashmap初始容量较小,所以为了让高位参与hash过程,hashmap高位对低位做了一个异或操作,这样就可以提高hashmap的效率
hashmap的rehash过程大致是这样,假设原来容量是16,对应6的位置放了一些对象,扩容后会导致hash值发生变化,部分6会在原地,部分会去22,这是因为多异或了一位
面试官:HashMap是不是线程安全的
我:hashmap根本没防线程线程安全问题,用ConcurrentHashMap,ConcurrentHashMap工作过程大致是这样,它会对比如说有容量是16,我对第三个操作就会对第三个加锁,在高并发的过程中,我同时
操作3,5他们是不会互相影响的。
面试官:那它是怎么加锁的呢?
我:主要是借助Segment这个数据结构的,具体怎么样的数据结构没说上来
面试官:线程池有哪些参数
我:核心线程数,最大线程数,最大空余时间,时间单位,队列,饱和拒绝策略
面试官:消息头了不了解
我:了解一点,消息头里会用4位一个·对象的年龄,因为只有4位,所以二进制只能表示到15,一个对象就最大的年龄只能为15,消息头里也会表示加锁状态,比如说是偏向锁等等
面试官:锁的状态有哪些
我:有无锁、偏向锁、轻量级锁、重量级锁。当一个加锁对象只有一个线程访问时,那么它就是偏向锁,当出现线程竞争但不激烈时,偏向锁就会升级为轻量级锁,当竞争很激烈时,就会向操作系统申请一个重量级锁
面试官:synchronized怎么实现加锁的
我:synchronized底层其实是像操作系统去实现加锁的。我记得会执行一个lock指令,具体忘记。程序运行在jvm中,jvm是由c++写,所以底层是通过c++去调用操作系统的
面试官:CAS了不了解
我:了解,但自己没用过,通过加锁的方式会让线程休眠唤醒,这个过程是比较耗时的,所以CAS干脆让它不停的自旋,通过dowhile实现,就比如说你要修改一个变量x,它的值是6,在你修改
它之前你先回去获取一遍他的值,如果现在值还是和你获取的一样,那么就可以修改,如果变成7了说明有线程更新过了,那么你需要重新获取。我提到我在学习过程中,觉得这种模式的CAS不能保证线程安全
因为判断+更新这不是一个原子操作,会不会存在判断通过的同时另一个线程完成了修改。我说我后来在网上查询的过程中了解到,CAS其实底层还是会去调用一个lock的汇编命令
面试官:ABA问题
我:ABA问题我在网上学习过程了解到,它其实跟会计挪用钱一样,解决办法就是引入版本号。
面试官:https了不了解
我:因为http在通信过程中数据都是可见的所以不安全引入了https,https主要是通过加密的方式来解决这个问题,加密方式又分为对称加密和非对称加密,对称加密就是通过相同的秘钥进行加密解密,非对称加密分为公钥和私钥
非对称加密和对称加密的效率是不一样的,对称加密的效率更高,所以先通过非对称加密,然后通过对称加密客户端在向服务端发送请求的过程中,先会把自己所支持的加密协议发送给服务端,服务端会从中挑选出合适的作为此次通讯协议。中间我说的有点混乱,因为这里其实有很多细节,但我语言组织没说清楚。最后实在说不清了,我就这么说就是现在服务端要把一个公钥传递给客户端,为了要保证公钥安全,需要向CA申请一个证书,客户端拿到证书后,会用内置的CA的公钥进行解密,因为这个公钥是内置的,所以不会在传递过程出现问题。然后客户端生成秘钥通过公钥加密发送给服务端,服务端通过私钥解密,之后就通过秘钥进行加解密。
面试官:GET和POST了不了解
我:了解,GET和POST表面上存在一些差异,例如get通过url传递参数,post通过request body传递参数,但他们的本质都是通过TCP。就好比车子分为大卡车和轿车,但他们的本质都是车。做get和post区分本质上是为了让通讯过程更加有序。其实get里也可以放入request body,post也可以通过url传递参数,但这是看服务端的,有些服务端会帮你处理,有些不会
面试官:SSL和TLS的区别
我:我不太清楚,我只知道TSL是SSL的扩展,但具体原理不太清楚
面试官:算法
我:敲完
大致就这些问题,可能会有遗漏,期间面试官也没告诉我哪里说得有问题
全部评论
(12) 回帖