关于java:Java开发面试题分享带答案

3次阅读

共计 7690 个字符,预计需要花费 20 分钟才能阅读完成。

出于篇幅思考,这篇文章给出了 10 个专题,每个专题给出了大概 4 道题的答案,残缺 200+ 题的答案 PDF 文档能够私信我。

Java 面试宝典产生自我筹备面试的过程,过后网上找了些试题,然而没答案,而后一边梳理本人的常识,个别联合本人平时钻研的常识和工作教训,本人对试题进行了整顿,解答。

也凭借着这次梳理,面试一路过关斩将,offer 收割率 100%。面了头条,和美团的 3 个事业部,均播种 offer。

也预祝各位校招的敌人,斩获称心的 offer

一:Java 根底

  1. String,Stringbuffer,StringBuilder 的区别。

答:String 是 final 类,⽆法继承,也⽆法被批改,每次批改都会创立新的 String 对象。

Stringbuffer 和 StringBuilder 则能失常被批改,两者的区别是 StringBuffer 每个办法都加了锁,是线程平安的。

  1. JAVA8 的 ConcurrentHashMap 为什么放弃了了分段锁,有什么问题吗,如果你来设计,你如何设计。

答:在 1.8 之前,ConcurrentHashMap 通过一个大⼩为 16 的 Segment 数组,这 16 个 Segement 继承自 ReenterLock,相似 16 把锁平均的保护着所有的桶。每次写操作将会锁住 1 个 segment 下所有的桶,锁力度较大,会升高反对的并发数。所以 1.8 进行了优化,采纳了更细力度的锁,hash 后,如果没有相干的桶,不加锁,间接通过 Unsafe 的相似 CAS 操作将值放入,如果有桶,则对这个桶加锁,其余桶的节点仍然能够失常操作

  1. 继承和聚合的区别在哪。

答:继承次要形容的是‘A is B’的关系,而聚合形容的是‘A has B’的关系,个别状况下,优先应用聚合,因为继承可能会继承父类中一些不必要的属性和办法。然而,如果须要向上转型,就须要用继承。

  1. 反射的原理,反射创立类实例的三种形式是什么。

答:当⼀个类加载实现后,会生成一个 Class 对象,Class 对象能够获取类的所有属性,⽅法等数据。

⽅式一:对象调用 getClass()办法

⽅式二:类名.class

⽅式三:Class.forName(全门路名称)

创立 class 对象后,间接调用 class 对象的 newInstance()办法即可创立实例

二:Jvm

  1. Jvm 包含那⼏大部分。

答:次要蕴含 4 个局部:类加载器,字节码执行引擎,内存模型,本地办法调⽤。

  1. 什么状况下会产生栈内存溢出。

答:个别在递归调用的时候容易产生。

虚拟机栈形容的是 Java 办法执行的内存模型,每个⽅法的执行都会创立一个栈帧,用于保留局部变量表,操作数栈,动静链接,办法进口等信息。

如果申请的栈深度大于虚拟机所容许的最大深度,将抛出 StackOverFlowError, 如果无奈申请所需的内存,则会抛出 OutOfMemoryError。

  1. JVM 内存为什么要分成新生代,⽼年代,长久代。新生代中为什么要分为 Eden 和 Survivor。

答:分为新生代,⽼年年代和长久代是为了不同的区域依据特点采纳不同的 GC 策略,例如新生代对象⼀般是朝⽣夕死,个别采⽤复制算法,辨别进一步分为一个 Eden 和两个 Survivor 区域。而老年代和长久带则个别采⽤标记革除算法。

  1. 具体介绍下 CMS 垃圾回收器器。

答:CMS 是⽼年代垃圾回收器,⽬标是最短的进展工夫。它的⼯作次要包含 4 个阶段:

(1)初始化标记,次要是标记老年年代中被 GCroots 和新生代援用的对象,须要 STW

(2)并发标记:从第一步对象开始,并发的实现标记

(3)从新标记:因为第二步是并发实现的,过程中对象援用可能发生变化,这一步次要是保障理论清理前标记是正确的,须要 STW

(4)并发革除:对标记对象并发进行革除

第一步和第三部尽管仍然须要 STW,但实现的工作较简略,较少,工夫较短;最耗时的实现标记过程和革除过程都是并发进行的,所以 CMS 能管制较短的进展工夫。

三:开源框架常识

  1. 简略介绍 Spring 加载流程。

答:资源的定位(Resource) -> bean 的解析(BeanDefinition) -> bean 的注册

(conncurrentHashMap)

  1. Spring AOP 的实现原理?解释几个 AOP 相干的专业名词?

答:原理:通过 IOC 和动静 ,aop 实质上是对被 bean 的加强,在 getBean() 获取 bean 的时候,初始化 bean 实现后会有一些后处理流程,aop 就是在这里实现的,如果发现 bean 有相关联的 advisior 或者 Interceptor,就会通过动静 * 对其进行加强。

专业术语:告诉(Advice): 切面的工作,切面是什么时应用,before,after,after-returning,afterthrowing,around;连接点(JoinPoint):利用中能插入切面的一个点;切点(PointCut):一个或多个连接点

  1. 讲讲 Spring 事务的流传属性。

答:spring 事务流传属性次要作用是处理事务⽅法被另一个事务办法调用的时候,spring 如何解决这些事务的行为。例如默认的流传属性 PROPAGATION_REQUIRED,就是如果以后有事务,则加⼊入以后事务,如果没有则新建一个事务。Spring 在 TransactionDefinition 中定义了事务的 7 种流传属性和 5 种隔离级别

  1. Spring 为什么把 bean 设计成默认单例的?这样设计有什么益处和害处

答:(1)防止频繁的创立实例,缩小开销,晋升性能;(2) 防止频繁创建对象导致 OOM 或者频繁的 GC;(3)能够充沛利⽤缓存,放慢获取速度

它的劣势也比拟显著,因为⼤家共⽤一个 bean,所以多线程环境下可能呈现线程平安问题

四:操作系统

  1. Linux 下 IO 模型有几种,各⾃的含意是什么。

答:5 中 IO 模型:阻塞 IO 模型,⾮阻塞 IO 模型,IO 复用模型,信号驱动 IO,异步 IO

阻塞 IO:过程始终阻塞,直到数据拷贝实现。

⾮阻塞 IO:通过重复调用,内核如果数据没筹备好,会立刻返回失败,上游决定持续重试,直到筹备好。数据拷贝过程仍然是阻塞的。

IO 复用模型:应用 select,poll 或者 epoll,仍然会阻塞,然而能够同时监听多个 IO 端口,哪一路路筹备好了,就优先解决哪个。

信号驱动 IO:⽴即返回,当数据筹备好了,向调用过程发送一个信号。

异步 IO:数据筹备好后,内核实现后通过回调函数告诉用户过程

  1. 平时⽤用到哪些 Linux 命令。

答:cd, mkdir ,touch, cp, vi, cat, netstat, kil,top

浏览⽂文件:cat more less

看⽇志:tail -n100 -f cantina.log

wc -l(看文件行数) -c(看文件的字节数)

top 看负载,cpu

df du 看磁盘使用率。df -h du -d1 -h /user

iostat -d -k 看磁盘 IO

free -m 看内存使⽤用状况

  1. 介绍下你理了解的操作系统中线程切换过程。

答:过程切换个别发⽣于中断,异样或者零碎调用的时候。此时,

(1) 被中断的过程 A 保留以后的高低⽂信息,而后挂起,批改线程状态,进入

相干过程队列。

(2) 复原 B 过程的上下文信息,调配 cpu 工夫片进行解决

  1. 过程和线程的区别。

答:过程操作系统资源分配的根本单位,线程是任务调度执行的最小单位。个别一个过程会蕴含多个线程,线程是轻量级的过程。

开销:过程有⾃己独立的代码和内存空间,切换开销较大,⽽多个线程共用过程的代码和数据空间,每个线程有⾃己独立的线程栈和程序计数器。

五:多线程

  1. 多线程的几种实现形式,什么是线程平安。

答:通过继承 Thread,或者实现 Runnable 接⼝

也能够通过线程池的⽅式,实现 Callable 接⼝

当多个线程拜访某个类时,不须要采取额定的同步措施,这个类仍然能体现出正确的行为,这个类就是线程平安的。

  1. volatile 的原理,作用,能代替锁么。

答:volatile 润饰的变量在写数据的时候,JVM 会主动向处理器加一个 lock 指令,处理器收到 lock 指令后会将新批改的值立刻回写到主内存,同时导致此变量在其余工作内存的值生效。

能够用作轻量级的同步形式,它能保证数据在各个线程的可⻅性,也能防止指令重排序。然而 volitaleb 并不能代替锁,volatile 尽管能保障可见性,如果对 volatile 变量的操作不依赖以后值,那就没问题,但如果依赖,那就是多步操作,例如 i++,仍然须要加锁。

  1. sleep 和 wait 的区别。

答:sleep 是 Thread 类中的静态方法,⽽ wait 是 Object 中定义的一般办法。两个办法都会开释 cpu 资源并使线程进入 waiting 状态,然而 sleep 不会开释锁,⽽ wait 会开释锁。

  1. Lock 与 Synchronized 的区别。

答:第一,实现⽅式不一样。synchronized 是通过字节码层⾯面进行⽀持的,⽽ lock 底层是通过
AbstractQueuedSynchronizer 实现。lock 加锁的⽅形式,以 UnfairLock 为例例,就是尝试去 setState, 如果胜利就给 state 加 1,如果失败,就排队到队尾,期待锁持有者的唤醒。开释锁就是给 state 减 1。

第二,Lock 相⽐比拟于 synchronized 性能更加的丰盛。例如 trylock 尝试去加锁,带过期工夫的加锁,偏心锁和非偏心锁等。

六:网络常识

  1. http1.0 和 http1.1 有什么区别。

答:(1)http1.1 ⽀持长链接,通过申请头的 keep-alive,1.0 则是短链接的,每次申请都会建⽴ tcp 连贯。

(2)减少 host 字段,之前认为每台服务器都有一个惟一的 ip, 但随着虚构技术的倒退,一个服务器上能够存在多个虚拟主机,它们共享一个 ip 地址。

(3)新增状态码 100,客户端先发一个不带内容的申请头,如果服务器承受就返回 100,而后客户端在持续其余申请,⽤于试探服务器端是否接管申请,还节俭带宽。

(4) 引⼊了了 Chunked transfer-coding 来解决下面这个问题,发送方将音讯宰割成若干个任意⼤小的数据块,每个数据块在发送时都会附上块的长度,最初用一个零长度的块作为音讯完结的标记。这种办法容许发送方只缓冲音讯的一个⽚片段,防止缓冲整个音讯带来的过载。

(5) 在 1.0 的根底上加⼊入了一些 的新个性,当缓存对象的 Age 超过 Expire 时变为 stale 对象, 不须要间接摈弃 stale 对象,⽽是与源服务器进行从新激活

  1. TCP 三次握手和四次挥手的流程,为什么建设连贯要 3 次,2 次不行,而断开连接要 4 次

握手须要 3 次,是因为 tcp 是双向通信协定,2 次握⼿手只容许一方建设连贯,而另一方则抵赖它,这意味着只有一方能够发送数据。所以须要 3 次握手达到单方相互确认能够发和接收数据。

建设连贯的 3 次握手的第二次信号,同时发送了 ack 和 syn,所以绝对于断开连接少 1 次发送流程。当客服端向服务端发送断开 FIN 申请时,示意客户端不会再向服务端发送数据了,然而客户端可能还有数据没接管完,服务端还须要持续向客户端发送残余的数据,当服务端也没数据发送给客户端时,服务端在发送断开申请,客户端进行确认即可,所以是 4 次握⼿手。

  1. 说说你晓得的几种 HTTP 响应码,比方 200, 302, 404。

答:2** 个别指申请胜利,例如 200 胜利。

3** 指重定向,301 永恒挪动,302 长期挪动。

4** 指申请谬误,404 未找到,403 禁止。

5** 指服务器异样,500 服务器外部谬误,503 服务不可⽤。

七:架构设计与分布式

  1. 分布式集群下如何做到惟一序列号。

答:uuid -> segment 获取号段计划 -> segment+ 双 * -> snowflake。具体的阐明能够查看美团技术公众号对应文章

  1. 如何应用 redis 和 zookeeper 实现分布式锁?有什么区别优缺点,会有什么问题,别离实用什么场景。

答:简略的 redis 分布式锁能够通过 setnx 命名,对同一个 key 去 setnx 1, 因为只有一个会胜利,所以就达到了加锁的目标,然而这会有个问题,就是因为 value 都是 1,所有就有可能锁会被其余客户端开释,所以个别采取的措施就是 value 是随机数或者工夫戳。但这个仅是和单机的 redis,如果 redis 是集群,主的数据还没来得及同步到从,主挂了,那么锁就生效了,其余客户端就能再次获取锁了。

所以 redis 作者提出了 redlock, 客户端向多个节点申请锁,每个节点设置远小于锁过期工夫的等待时间,当胜利的节点个数⼤于一半,则获取胜利。但这和下面单节点一样会有问题,有节点产生解体或者有节点阻塞导致过期等都同样会有问题

  1. REST 和 RPC 异同?

答:(1) ⾯向的对象不同:REST 是⾯向资源的,而 RPC 是⾯向服务,⾯向办法的

(2) 所属类别不不同:REST 次要是用在 http 中,而 RPC 次要是近程调⽤

  1. Zk 怎么保障多客户端同时创立节点,只有一个创立胜利。

答:通过查看 zk 的源代码能够发现,createNode 的实现会先依据节点的 path 获取下级门路的父节点,并用⽗节点对后续的创立节点操作进行加锁。当父节点 getchildren 蕴含以后节点时,间接失败。

八:数据库常识

  1. Mysql MyIsam 和 InnoDB 引擎索引构造有什什么区别。
  1. 数据库隔离级别有哪些,各自的含意是什么,MYSQL 默认的隔离级别是什么。

答:隔离级别有 4 种

未提交读:最低级别,只保障不读取物理损坏的数据

提交读:能够防止脏读

可反复读:默认级别,可能防止脏读和不可反复读

可序列化:最⾼级别,能够防止脏读,不可反复读和幻读。

  1. 什么是幻读。

答:一个事务依照雷同条件读取以前读取过的数据,发现其余事务插入了满足条件的数据。防止幻读个别采取的措施是采纳间隙锁。不可反复读关注的是数据被其余事务批改,而幻读关注的是其余事务插入了新的符合条件的数据。

  1. Mysql 的索引原理,索引的类型有哪些,如何创立正当的索引,索引如何优化。

答:索引应用 B+ 树对数据进行疾速的检索。

B+ 树索引,hash 索引,前缀索引,全文索引等等。

创立正当理的索引:(1)首先你得分明你业务中的应用场景,哪些字段会被常常用做检索条件,而后思考字段的离散水平

(2) 依据须要适当的建设索引,不要适度,索引不是越多越好

(3) ⻓字段能够思考前缀索引,多字段能够思考建设联结索引

(4) InnoDB 还能够充分利用汇集索引

索引的优化我认为次要是优化有索引但没用上的状况:

or 的每个条件都必须有索引,不然不会⽤索引;

是否是复合索引的前列;

Like 含糊查问含糊匹配 % 放在最后面;

字符串没加引号导致的隐式类型转换

九:音讯队列

  1. 音讯队列的应用场景。

答:音讯队列个别用于零碎间的解耦,例如订单组产生订单相干的各类 mq 音讯,关怀订单操作的零碎自行申请相干的 mq 即可。

异步解决,相比拟于 rpc 的同步调⽤,须要期待后果返回,mq 是异步解决的,例如库存的扣减主流程仅仅依赖 redis,而扣减 DB 能够通过 mq 实现最终一致性。

刹时流量的平滑削峰解决,对于刹时的大流量,能够将其放⼊ mq 中,生产端一直拉取工作进⾏解决,做到平滑削峰。

  1. 音讯的重发,补充策略。

答:生产端生产胜利后都会给予消息中间件确认音讯,中间件即可将相干的音讯删除。然而因为网络的不牢靠或者其余因素,消息中间件为了保障音讯的肯定送达,个别会采取各种重发措施,个别常见的措施有超时重传,音讯确认机制等。

  1. MQ 零碎的数据如何保障不失落。

答:各大消息中间件采取的措施其实⼤同小异,相互借鉴,以 Kafka 为例。

发送端个别是通过 ACK 应答机制,当 kafka 接管到音讯后,就会产生应答音讯,能够配置是不须要应答,还是 leader 应答,还是所有的 follower 都实现再应答。

音讯队列个别是通过长久化到文件系统,节点的主从机制,曾经主节点的 * 等机制。生产端则个别是通过应答机制,以及超时重传来保障音讯的可靠性的。Kafka 通过位点来控制数据的不失落

十:缓存

  1. 如何避免缓存击穿和雪崩。

答:(1)缓存穿透:指的是当缓存查不到的时候,去查数据库。当有人⽤大量量的不存在的 key 去歹意查你的缓存时候,就会有⼤量的申请打到数据库,对数据库造成压力。个别能够采取的措施是,查问缓存前在减少一层过滤,例如通过 bitmap。

(2)缓存击穿:指个别被高频拜访的热点 sku,当这些热点 sku 过期了,大量的申请就会打到数据库。能够思考采取加锁,或者设置更⻓的过期工夫,甚⾄不过期。

(3)缓存雪崩:指大⾯积的 key 同时过期,申请全副申请到了 DB。采取的方法能够 key 的过期工夫减少一个随机数。

其余还能够采取的措施,能够单机通过 Guava 做防刷。其实后面问题的要害都是对数据库造成压力,所以能够在数据库端做好限流或者分布式锁。

  1. Redis 的数据结构都有哪些,各自都适宜什么样的场景。

答:String, list, hash, set, zset

String 利用最宽泛,适宜各种 key-value 数据的存储,List 底层是双向链表,适宜用作列表,队列等

Hash 适宜对象的存储

Set 适宜去充场景下汇合的存储,set 还提供交并差集⽀反对

Zset 是有序的 set,能够⽤来实现 PriorityQueue

  1. Redis 的应用要留神什么

答:(1)冷热数据离开存储,不同业务数据离开存储

(2)标准 key 的命名,依据不同业务设置适合的命名空间

(3)留神垃圾回收,key 设置适合的过期工夫

(4)⼤文本数据能够先进行压缩

(5)hash,set 的 key 的 field 不应太多,能够依据业务多用几个 hash 和 set

(6)设计 sharding 机制

  1. redis 和 mem*d 的区别。

答:redis 和 mem*d 都能很好的实用缓存,它们应用内存进⾏行数据的存储。次要有如下⼏个区别:

(1)⽀持的数据类型:mem*d 仅反对简略的 key-value,而 redis ⽀持更丰盛

(2)线程模型:redis 是单线程的,mem ⽀持多线程,数据量大时,mem 具备肯定的劣势

(3)长久化:mem 纯内存的,断电,啥都没了了。redis ⽀反对 rdb 或者 aof 两种⽅式的长久化

(4)内存治理理:mem 将内存划分成一块块固定⼤小的 chunk 内存块,尺⼨寸雷同的块组成 slab class,当存储数据时,找一个最合适的 chunk 进行存储,可能会产⽣生碎⽚片,内存利⽤率不高。⽽ redis 通过对 C 语⾔言的 malloc/free 进行包装,将申请的内存块的⼤小搁置在内存块的头部区域,做到精准的内存申请和开释。同时,当内存不不够的时候,mem 采⽤用 LRU 进⾏删除,而 redis 除了 LRU 还能够使⽤虚拟内存将局部 value 转移到磁盘中,key 仍然保留在内存中。

(5)分布式:mem 自身不反对分布式,得⾃己在客户端实现。而 3.0 版本开始,redis 原⽣⽀持集群

如果本文对你有帮忙,别忘记给我个 3 连,点赞,转发,评论,

咱们下期见!答案获取形式:已赞 已评 已关~

能够说这一篇(宝典),熟知本文 80% 以上内容,找个开发工作问题不大。对 3 - 5 年教训的敌人,也是疾速复习的利器!本次的内容大抵的就介绍到这里啦,因为内容太多,只能简略介绍到这里,如有须要以上内容的完整版,大家能够私信我获取哦~~ 后盾关注我后私信回复:【666】即可获取

正文完
 0