- 面向对象三大特征(没啥好说的,但是最好结合个人理解);
封装、继承、多态
封装就是将数据和基于数据的操作封装起来,对外提供一定的接口,可以通过这个接口和外界进行交互,用户不必知道内部的细节,但可以通过对外的接口访问该对象。
继承:一个类继承另一个类,将会继承父类中所有的属性和方法
子类可以拥有自己的属性和方法,即子类可以对父类进行拓展
子类可以用自己的方式实现父类的方法
多态:分为编译时多态和运行时多态。
编译时多态指方法的重载
运行时多态指的是对象引用所指的具体类型只有在运行时才会确定,具体表现为父类的引用指向子类的实例。
结合实际谈谈对三大特征的使用与理解吗?(结合了项目用到的内容,分析封装继承多态的应用与理解,SDK工具封装,访问控制,父子集成扩展,接口扩展,多态运行时调用,多态底层虚函数实现,invokevirtual关键字,解析/分派。主动聊的很深)
GC的几种算法(从计数->引用判断对象是否已死,优缺点分析;分代假说,为何分代,跨代部分解决方案; 由分代假说引出三种回收算法,优缺点,在各回收器上的应用;深入三色标记,并发问题;CMS/G1介绍,这里说的非常多了,问了面试官是否继续。)
判断对象是否存活(引用计数法、)
标记-清除法、标记-复制法、标记-整理法
- 谈谈你了解的几种垃圾回收器(介绍了CMS和G1,原理、过程、优缺点、对比)
GMS:是一个真正意义上的并行垃圾回收器,采用标记整理法
过程:并发标记、并发清除、
- 想要在指定时间结束垃圾回收,选用哪种垃圾回收器(这里忘记了G1的设计初衷——停顿预测模型,没回答出来G1,答的parallel scavenge);
G1垃圾回收器,把堆平均划分为一个一个的小块,垃圾回收时,按优先级优先回收空间。
- 线程池的几个参数(常规八股);
核心线程数、最大线程数、空闲线程存活时间、时间单位、工作队列、线程工厂、拒绝策略
工作队列分为:基于数组的有界阻塞队列、基于链表的无界阻塞队队列、不缓存任务的阻塞队列、具有优先级的无界阻塞队列。
四种拒绝策略:直接执行、丢弃任务抛出异常、丢弃任务什么也不做、抛弃进入队列的最早任务,尝试将这个任务放入
线程池的工作过程:
1.提交一个任务后,先判断核心线程是否都在工作,如果有空闲的,就执行工作
2.如果都在工作,则判断阻塞队列是否满,没有满则放入阻塞队列等待
3.如果阻塞队列已经满了,则判断是否达到最大线程数,如果没有,则创建一个非核心线程执行任务
4.如果已经到达最大线程数,则执行拒绝策略
- JMM内存模型(常规八股);
Java之间的线程通信由JMM内存模型控制,JMM决定一个线程的共享变量的写入何时对另一个线程可见。
JMM内存模型定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存中,每个线程都有一个私有的本地内存,本地内存中存储了该线程中对共享变量的读/写副本。
- volatile和synchronized(常规八股,深度方面,简单说了happens before,MESI,#Lock关键字,锁升级过程,objectMonitor对象里的队列与状态字)
1.volatile的理解:volatile保证了共享变量的可见性
一个线程修改这个值时,另一个线程能读到这个修改的值
2.volatile的内存语义:当写这个变量时,JMM会把volatile修饰的值从该线程的本地内存刷新到主内存
当读这个变量时,JMM会把该线程的本地内存设为无效,从主内存中读取值
3.volatile保持可见性的原理(CPU)
汇编代码中出现Lock前缀的指令
多核CPU中:将当前处理器的缓存的值刷新到内存中;写回操作会使其他CPU中的缓存的值无效。
synchronized的理解:
synchronized可以修饰代码块和方法
修饰代码块时,通过反编译可以看到字节码中有monitorenter、moniterexit指令,这个指令对应着对monitor的加锁和解锁
修饰方法时,会有方法头会出现ACC_SYNCHRONINZED标识,也会对应一个monitor变量的加锁和解锁
synchronized修饰代码块时,锁住的是()传入的对象
修饰静态方法时锁住的是class类
修饰普通的方法时锁住的是对象
后来引入无锁->偏向锁->轻量级锁->重量级锁
- 介绍一下Java不同层面的锁(JVM层面与JDK层面,就是synchronized+Lock,优缺点、对比、AQS)
synchronized
- 很多短任务线程,选择synchronized还是lock(场景题,有点复杂,看规模,当时回答的有点错误:锁竞争小时,synchronized和lock效率没差,偏向模式下(单线程读写)甚至高于lock,但是并发量上升时锁撤销会大幅影响性能,稳定自适应轻量级锁状态下,线程接近交替运行,或者说短任务线程多,基本一样,因为都是自旋,大量任务并发竞争时,随着任务量的增大,synchronized的效率会远小于lock,因为重量级锁会频繁切换内核态与用户态;大量长任务,只能重量级锁。以上是个人所总结,有不正确的还请指正)。
- 7层网络,4层网络,5层网络,各层有哪些协议(normal)
- 已经封装好的消息,不考虑DNS等,怎么寻址(normal)
- 局域网内怎么寻址,网关怎么找到(DHCP,忘了,但是答出来联网时已经获得了网关)
- 网际路由协议,怎么确定最短路由(BGP,忘了,直接说时间久远)
- 反问。
作者:酥皮_Si
链接:https://www.nowcoder.com/discuss/928781?type=2&channel=-1&source_id=discuss_terminal_discuss_hot_nctrack&page=2
来源:牛客网
- 部门介绍(交叉面,hr面确定部门)
- 自我介绍
- sqlserver和MySQL区别(堆组织数据、B+树组织。锁)
- 什么时候是表锁(首先纠正问题描述:什么时候退化成行锁,然后向下展开,主键索引、唯一索引、普通索引、等值查询、范围查询、锁过滤、ICP优化);
- MVCC(隐藏字段,readView结构体,ids,undo页)
- redo,undo,binlog(结合了redis的持久化,讲了内部XA,undo页组织,purge线程。数据库回答完,说三五年经验的都没我掌握的多,我。。。)
- DNS(开扯,DNS过程,DNS负载均衡)
- 计网:三次握手、四次挥手(开扯,啥都扯了,tcp头在握手中的变化:seq、ack、syn、窗口大小,socket连接过程对应,半连接、全连接队列,洪泛,cookie,半连接溢出策略,挥手过程,time_wait)
- Q:要再深入一点吗?A:不用了,那再说下第三次握手失败会发生啥吧(参见小林图解,重试次数,重试时间)
- 讲一下GC算法吧(开扯:分代假说,分代,三种算法,优缺点,常见垃圾回收器的应用)
- 设计模式(结合项目开始扯淡,责任链、策略模式、ThreadLocal,深浅拷贝)
- 项目:心跳怎么实现的?
- 项目:重复通知怎么回事,怎么解决的(两个层次)
- 项目:redis除此之外呢,还有啥(缓存);
- 项目:对redis依赖太过了,崩了咋办(cluster,真崩了就罕见了,还能咋办,发通知,重启);
- git用过哪些命令(pull,add,commit,push,fetch,diff,merge);
- C#和C++也会是吧?(会用会用);
- 那讲一下函数式编程吧(一开始听成面向过程,后来反应过来,讲了Java怎么实现的函数式:单一方法接口,C++函数指针,js方法对象,讲了lamda怎么用)
- 反问