面试刷题12-2

1. Java线程的状态

Runnable状态与操作系统中进程运行状态的关系

2. sleep和wait的区别

从资源层面来看,sleep占有哪些资源???

sleep不释放锁

什么是锁?

3. 乐观锁与悲观锁

平时有没有用过乐观锁,怎么用的

CAS

4. CAS原理。有用过CAS吗

5. 什么是内存可见性,怎么保证的,可见性和原子性有什么关系?

6. 解释一下volatilesynchronized,两者一样吗?volatile能保证线程安全吗?

7. 索引的种类?什么是聚族索引?什么是覆盖索引?

8. 数据库的隔离级别有哪些

9. Redis出现多个Client同时修改redis服务器中同一个key怎么办?(redis并发竞争问题?)

10. redis的事务跟数据库的事务一样吗?

11. 一道算法题:

输入:1->2->3->….>n-1>n

输出:1->n->2->n-1->3->n-2…..

 

二面:

1. JVM

2. MVCC是什么?原理?

3. 乐观锁与悲观锁

4. volatile的原理?volatile有那些应用场景,写下代码

答:单例模式

写的代码:

public class Singleton {

    private Singleton(){}

    private volatile static Singleton instance;

    public static Singleton getInstance() {

        if (instance == null) {

            synchronized(Singleton.class) {

                if (instance == null) {

                    instance = new Singleton();

                }

            }

        }

        return instance;

    }

}

  问:为什么要使用volatile修饰。

  答:为了防止指令重排序。

这行代码instance = new Singleton();实际上涉及到3个步骤

1.分配内存空间

2.初始化

3.instance指向分配的内存空间

23步骤是可以指令重排序的,如果不用volatile修饰,会造成

return一个未初始化的instance

继续问:synchronized(Singleton.class)已经保证了获取这个类锁的只能有一个线程,为什么还会出现这种情况?结合具体例子分析一下?

答:????

(感觉他是想让我分析一下,在不用volatile情况下,线程A与线程B同时执行这部分代码,如何才能出现return一个未初始化的instance)

5. 结合项目。

   项目中的注册登录模块。能记住登录用户吗?怎么做到的?

   Cookie与Session的区别?

   服务端是怎么验证用户的?生成的token有可能重复吗?

   客户端怎么存储token的?明文吗?如果被人截取怎么办,怎么保证安全性?

6. TCP/IP与UDP什么关系?

   TCP/IP是协议族,它的四层概念模型的传输层包含了UDP与TCP协议。

   那TCP与UDP有什么区别?

   UDP一对多怎么实现呢?

7. 什么是平衡二叉数

答:我先讲了一下排序二叉树,有什么缺点,然后讲什么是平衡二叉树

再问:给了个具体例子:

     10

    8  16

  6 9

这颗二叉树要新插入一个5怎么做?

答:5成为6的左孩子导致二叉树不平衡,要进行右旋转。

问:具体怎么旋转的,给你15分钟,代码实现一下

答:?????

8. 算法题:k个有序链表合并。要求讲一下时间复杂度。

 

 

 

 

 

 

实习:最好在大四上学期的六、七月份(秋招提前批)之前积累所有实习,然后就可以密集面试->以小博大->复盘总结->经验+1了,本科生不打算读研就逃课去!!!(大三整个学期是最好的时间段,重要专业课可以b站自学),找实习的项目可以用mooc/mit/cmu/github上跟着学的 or 开发类比赛(一般和算法竞赛相悖,选了算法竞赛要天天刷题比赛,再去兼顾开发类很难。看你热爱和天赋,早做打算)的(仿中间件 or curd的话最好有分布式等加成),校招项目就加上实习公司的项目,而且实习一定要边实习边记录以免忘记内容和难点,因为很难一边实习一边秋招!要以小博大,先从不知名公司实习起;然后用小公司实习经验去博取大厂机会,可以大厂转正(转正很可能是白菜价),在部门呆的不满意就秋招。

 

比赛&项目:可以参加一些知名的比赛,如果参加了ICPC类基本大一大二就要天天刷题、打出成绩了(不是铁就可以,反正提高自己的算法能力,不打ICPC就刷LC)至少大三下学期必须实习;如果参加中间件、软件杯之类的,也要大一大二大三上参加,其余时间都是晚了的。项目的话最好是实习的项目,自己做的玩具面试官一般瞧不上。面经很多,找Java看这个https://www.nowcoder.com/discuss/344311?type=0&order=4&pos=25&page=3https://www.nowcoder.com/discuss/331574?toCommentId=4824987;找cpp看这个https://www.nowcoder.com/discuss/338853?type=0&order=4&pos=5&page=2

 

校招:提前批、提前、提前批(我就是因为实习(提供的住宿酒店信号不好就没怎么投)错过了6-8月的提前批后悔终身,离职后9月中才开始大投的,如果时间能重来,信女愿一生吃素);策略同样是以小博大,先找不想去的公司练手,再去面试大厂。

 

价格:这个我没argue过,因为没资格。不过这个估计是以大博小,用大厂白菜/sp博取中小厂sp/ssp吧。

 

忠告:你不是三个月就能成功(坚持、聪明、高学历)的大佬,而是间歇性踌躇满志,那就老老实实拉长时间线早做准备,不要以为临门一脚就能得到满意的结果!找当然能够找到,但是扪心自问,你觉得这是尽力后最好的结果吗?

 

自省:这都是血泪经验,本人踩过的坑有在算法竞赛上没有很大天赋、较吃力还去死磕,没有及时抽身而退,应该早点实习(这方面那个双非前端大佬家欣做的很好)从实践学习,不过当时还是有竞赛保研的侥幸在里面,也许选了哪条路都会后悔;提前批被【春招投太早导致大厂一轮游】吓怕了,所以秋招基本没投提前批,有些大厂也是因为怕冷冻期而投晚了,不过投早了估计也准备不到位而挂,没有早点实习真的一步错步步错。


一面(电话面)

在第一次面试中主要针对于之前所做的项目询问了一些细节。Java方面的问题则提问了Servelt的生命周期,线程的状态,加密算法(非对称,对称,MD5)以及数据库事务ACID四大特性。

二面(电话面)

在第二次面试中,面试官问到了Java的内存模型(原子性,有序性,可见性),ava中集合的层次,JVM的垃圾回收机制,HashMap、Hashtable、ConcurrentHashMap的区别,同步器实现机制。还问了我使用过哪些ORM框架,有一次问到了数据库事务的四大特性,还问了注解处理器,以及原子类底层机制(cas, Unsafe)以及快排实现方式。

三面(视频面)

第三次面试中,问了一些相关的技术问题了,主要问了ES的检索机制(query-then-fetch),其次还针对于一些具体的场景设定问了更多的问题,面试官问如果现在要搜一个词,按相关度排序,如何获取排名在(100-120)之间的文档,针对于“用户打车付款-滴滴后台-支付宝后台”设计一个一致性处理方案,此外还问了数据库事务特性以及隔离级别等。


看《Java并发编程艺术》随意记录摘抄一下

  • 并发编程的目的:为了让程序运行的更快

​ 但并不是启动更多的线程就能让程序最大限度的并发执行,因为这会面临线程上下文切换、死锁等问题。

  • 如何减少上下文切换?

    无锁并发编程、CAS算法、使用最少线程、使用协程。

  • 并发编程中避免死锁的几个常见方法

    • 避免一个线程同时获得多个锁

    • 避免一个线程在锁内同时占有多个资源

    • 尝试使用定时锁,使用 lock.tryLock(timeout) 来替代使用内部锁机制

    • 对于数据库锁,加锁和解锁必须在同一个数据库连接里,否则会出现解锁失败的情况

  • volatile关键字的作用?
    在多核处理器编程中保证了共享变量的可见性

  • volatile实现原理?

    以X86处理器为例,在编译出来的汇编代码中,有带 Lock 前缀的指令。该指令会导致:

    • 将当前处理器缓存行的数据写回到系统内存

    • 一个处理器的缓存回写到内存会导致其它处理器的缓存无效

  • synchronized实现同步的基础:Java中的每一个对象都可以作为锁,具体表现为

    • 对于普通同步方法,锁是当前实例对象

    • 对于静态同步方法,锁是当前类的Class对象

    • 对于同步代码块,锁是synchronized括号里配置的对象

  • synchronized用的锁存在于Java对象头

  • 锁的几种状态

    无锁状态、偏向锁、轻量级锁、重量级锁

    锁可以升级但不能降级

  • 偏向锁

    • 目的:使线程获得锁的代价更低

    • 当一个线程访问同步块获取锁时,会在对象头和栈帧的锁记录里存储锁偏向的线程ID,以后该线程进入和退出代码块时,不需要再用CAS进行加锁解锁,只需简单测试一下对象头的Mark Word里是否存储着指向当前线程的偏向锁。如果测试成功,表明该线程已经获得了锁;若测试失败,再测试Mark Word中偏向锁的标识是否设置为1(表明当前是偏向锁),如果没有设置,采用CAS算竞争锁;如果设置了,尝试使用CAS将对象头的偏向锁指向当前线程。

  • 锁的优缺点对比

    • 偏向锁:加锁和解锁不需额外的消耗;但如果线程间存在锁竞争,会带来额外的锁撤销的消耗;适用于只有一个线程访问同步块的场景

    • 轻量级锁:竞争的线程不会阻塞,提高了线程的响应速度;但如果始终得不到锁竞争的线程,使用自旋会消耗CPU;适用场景:追求响应时间、同步代码块执行速度非常快

    • 重量级锁:线程竞争不使用自旋,不消耗CPU;但线程阻塞,响应时间缓慢;适用场景:追求吞吐量、同步代码块执行时间较长

  • 原子操作的实现原理

    处理器如何实现原子操作?

    • 通过总线锁保证原子性
    • 通过缓存锁保证原子性

    Java如何实现原子操作?

    • 通过锁、循环CAS实现

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值