某跨境电商独角兽Java实习面经|讲解
挑选了一篇牛客上关注度比较高的面经给大家做讲解分析和学习指引,期望对大家有所帮助~
面经原贴链接
1. 问题:说说对oop的理解
解析:: 这种“谈谈你的理解”类的问题属于开放性问题,面试官核心是想引入这个话题,然后通过你的回答来进一步探讨和延伸相关问题。所以这个问题你从多个方面回答都可以,例如谈谈 “面向对象oop”与“面向过程”的对比,说下面向对象的三大特性等等。 考察的是对“面向对象基础”的掌握
参考回答:
OOP,即面向对象编程(Object-Oriented Programming),与之相对的是“面向过程”编程。两者的主要区别在于解决问题的方式不同:“面向过程”把解决问题的过程拆成一个个方法,通过一个个方法的执行解决问题。“面向对象”会先抽象出对象,然后用对象执行方法的方式解决问题。一般提到面向对象会提它的三大特性;封装继承多态。 简单说:"封装": 是指把一个对象的状态信息(也就是属性)隐藏在对象内部,不允许外部对象直接访问对象的内部信息。但是可以提供一些可以被外界访问的方法来操作属性。“继承”:不同类型的对象,相互之间经常有一定数量的共同点,同时,每一个对象还定义了额外的特性使得他们与众不同,继承是使用已存在的类的定义作为基础建立新类的技术,可以提高代码的重用,程序的可维护性,节省大量创建新类的时间 ,提高我们的开发效率。“多态”:表示一个对象具有多种的状态,具体表现为父类的引用指向子类的实例。
学习指引: 整体掌握面向对象基础这块 公开资料: 链接 资料链接
2.你接口和抽象类是怎么用的
解析:: 这个问题不是项目面试中问你怎么使用的,所以不用思索自己的项目,或者非要想一个例子出来,这样反倒容易把自己卡住。这就就当成一般性八股问题,你谈谈 接口和抽象类使用上的共同点和区别就行。(同样也属于面向对象基础的考察)
参考回答:
其实接口和抽象类有很多相似之处,例如:都不能实例化对象,都可以包含抽象方法,也都可以有默认方法(Java8可以用 default g关键字在接口中定义默认方法)。 当然,使用上的区别还是挺大的:1. 接口主要用于对类的行为进行约束,你实现了某个接口就具有了对应的行为。抽象类主要用于代码复用,强调的是所属关系 ; 2. 一个类只能继承一个类,但是可以实现多个接口; 3 接口中的成员变量只能是 public static final 类型的,不能被修改且必须有初始值,而抽象类的成员变量默认 default,可在子类中被重新定义,也可被重新赋值
学习指引: 整体掌握面向对象基础 资料链接
3.ConcurrentHashMap怎么做并发处理的?
解析: ConcurrentHashMap的并发处理相关问题是经典高频面试题,并且回答的时候一般需要将JDK1.7和JDK1.8中的实现方式都答一下。注意:回答这个问题可以笼统的回答一下,但是要做好面试官继续追问细节的准备。
参考回答:
Java 1.7中的ConcurrentHashMap并发处理: 在Java 1.7中,ConcurrentHashMap采用了分段锁的设计来实现并发控制。它将整个哈希表划分为多个段(Segment),每个段都是一个小型的哈希表,并且拥有自己的锁。当线程访问某个段时,只需要获取该段的锁,而不需要锁定整个哈希表。这种设计允许不同线程同时访问不同的段,从而实现了高并发性能。然而,这种分段锁的设计在Java 1.8中被废弃,因为随着硬件和JVM的发展,更细粒度的锁策略变得更为高效。
Java 1.8中的ConcurrentHashMap并发处理: 在Java 1.8中,ConcurrentHashMap进行了重大的改进,采用了更细粒度的锁策略和无锁技术来提升并发性能。它引入了同步控制(Synchronization Control),其中每个节点都可以被独立地锁定。线程在访问或修改节点时,首先会尝试使用CAS操作进行无锁更新。如果CAS失败,说明有其他线程正在修改该节点,当前线程会获取该节点的锁并进行同步操作。此外,Java 1.8还引入了红黑树来优化链表长度过长时的性能,并使用了内部类ForwardingNode来实现在扩容过程中的并发访问。这些改进使得Java 1.8中的ConcurrentHashMap在并发处理方面更加高效和灵活。
学习指引: ConcurrentHashMap要重点掌握,学习的时候也需要掌握大部分常考的细节问题,最好源码分析也能看懂。 公开资料: 源码 链接 面试题 链接
4.ConcurrentHashMap的get方法里有做并发处理吗
解析: 这个是上一个问题延伸出来的实现细节问题,也是属于常考问题之一,需要掌握;
参考回答:
有做并发处理,但是不是加锁等同步机制。get方法本身并不直接包含显式的锁或其他传统的同步机制,这是因为get操作只是读取数据,并不修改内部的数据结构,所以它可以在没有锁定的情况下安全地并发执行。然而,这并不意味着ConcurrentHashMap没有做任何并发处理来确保get操作的正确性,因为get操作有潜在的可见性问题,所以ConcurrentHashMap中的关键字段,如内部节点数组(Node<K,V>[] table),被声明为volatile。这意味着对这些字段的写入会立即对其他线程可见,从而确保了在并发环境下读取到的是最新的数据。
学习指引: 学习资料同上,掌握ConcurrentHashMap实现。源码 资料链接
5.对称加密与非对称加密
分析: 常见的加密算法还是需要掌握,对称加密与非对称加密其实在很多地方都有使用,例如https中其实就混合使用了这两种加密算法,当考察https/http的时候,大家也必须要能回答。
参考回答:
对称加密: 对称加密,又称私钥加密,其加密和解密过程使用相同的密钥。发送方使用密钥对数据进行加密,然后将加密后的数据发送给接收方。接收方使用相同的密钥对接收到的加密数据进行解密,从而得到原始数据。对称加密的优点在于加密解密速度快,适合处理大量数据。然而,其缺点在于密钥的传输和保管问题,因为双方必须确保密钥的安全交换和存储。
非对称加密: 非对称加密,又称公钥加密,使用一对密钥:公钥和私钥。公钥用于加密数据,而私钥用于解密数据。发送方使用接收方的公钥对数据进行加密,然后将加密后的数据发送给接收方。接收方使用自己的私钥对接收到的加密数据进行解密。非对称加密的优点在于密钥的传输更为安全,因为公钥可以公开,而私钥只需由接收方秘密保管。然而,非对称加密的加密解密速度相对较慢,不适合处理大量数据。但它非常适合用于数字签名和密钥交换等安全场景。
学习指引:
计算级网络也是校招生需要掌握,这里推荐整体学习 小林 coding的"图解网络": 公开资料: 系统学习资料链接 加密算法资料链接
6.MD5是啥,它是加密算法吗?加盐是什么原理,还了解其他加密算法吗
分析: 继续考察网络安全相关知识,MD5还是常用的一种技术需要掌握。
参考回答:
1.MD5不是加密算法。它是一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),更多地被用于确保信息传输完整一致,是数据完整性校验和数字签名等场景的重要工具。但MD5算法本身已被认为不够安全,因此在高安全性要求的应用中,建议使用更安全的哈希算法,如SHA-256或bcrypt等
2.加盐原理:为了增加密码的安全性,可以使用“加盐”技术。加盐的基本原理是在密码哈希过程中引入一个随机生成的字符串,即“盐值”(Salt),与密码一起进行哈希计算。这个盐值在密码哈希时被加入到密码中,但在验证密码时也需要使用相同的盐值进行哈希计算,以确保密码的正确性。
3.其他加密算法: AES:AES(Advanced Encryption Standard)是一种对称加密算法,被广泛应用于数据加密和解密。它提供了多种密钥长度选择,包括128位、192位和256位,以适应不同的安全需求。 RSA:RSA是一种非对称加密算法,它利用了一对密钥(公钥和私钥)来进行加密和解密操作。公钥可以公开,用于加密数据,而私钥则用于解密数据。RSA算法被广泛应用于数字签名、密钥交换和身份验证等场景。
学习指引:
常用加密算法,散列算法,掌握重点几个,其他做个了解: 公开资料:加密算法
7.DDoS攻击和CSRF攻击了解吗? 说一下
分析: 网络安全常考问题之一,需要掌握。能够简单描述原理即可。
参考回答:
DDoS攻击: DDoS(分布式拒绝服务)攻击是一种针对网络或服务的恶意行为,目的是通过大量请求拥塞目标服务器或网络资源,使其无法为正常用户提供服务。攻击者通常控制多个计算机或设备,形成一个攻击网络,同时向目标发送大量无效或高流量的请求,导致目标系统过载并崩溃。DDoS攻击具有难以防范和追踪的特点,是网络安全领域的一大挑战。
CSRF攻击: CSRF(跨站请求伪造)攻击是一种利用用户已登录身份,在用户不知情的情况下,以用户的名义执行非法操作的攻击方式。攻击者通过伪造恶意请求,诱导用户点击链接或执行某些操作,从而在用户与目标网站之间建立非法请求,实现攻击目的。例如,攻击者可能通过伪造转账请求,诱使用户点击,从而在用户不知情的情况下完成非法转账。CSRF攻击通常发生在用户已经登录并具有一定权限的情况下,因此具有较高的隐蔽性和危害性。为了防范CSRF攻击,网站通常采取验证请求来源、使用随机令牌等措施。
学习指引:
一文搞懂XSS攻击、SQL注入、CSRF攻击、DDOS攻击和DNS劫持 资料链接
8.类加载流程
分析: JVM 4重点+1了解:内存区域划分,垃圾收集,内存分配策略,类加载机制。类文件结构(了解)
参考回答:
Java类的加载流程可以简要描述为:首先,通过类的全名获取定义此类的二进制字节流;然后,将字节流所代表的静态存储结构转化为方法区的运行时数据结构;接着,在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口;最后,进行包括验证、准备、解析和初始化在内的步骤,其中验证是为了确保被加载的类文件信息符合JVM规范,准备是给类的静态变量分配内存并设置默认的初始值,解析是将符号引用转换为直接引用,初始化则是为类的静态变量赋予正确的初始值。这一过程由Java虚拟机中的类加载器完成,确保类能够正确、安全地被加载到JVM中运行。
学习指引: 1.面试学习:别背,先理解记忆,最后按照自己的话来输出: 资料链接
2.系统学习(推荐):经典书籍《深入理解Java虚拟机 第3版》|第7章 “虚拟机类加载机制”
9.JVM垃圾回收机制
分析: JVM 重点考察之一。但是这个问题太笼统的了,一样的策略,面试官想引入话题,根据你的描述来细问。
参考回答:
Java垃圾回收机制是Java自动内存管理的重要组成部分,旨在回收不再使用的对象占用的内存,防止内存泄漏。垃圾回收算法负责识别哪些对象不再被引用,即成为垃圾对象,常见的算法有标记-清除、复制、标记-整理等。而垃圾收集器则是执行垃圾回收算法的具体实现,负责在合适的时机触发垃圾回收,释放垃圾对象占用的内存空间。Java提供了多种类型的垃圾收集器,如Serial、Parallel、CMS和G1等,以满足不同应用场景下的性能需求
学习指引:
1.面试学习:资料链接 2.系统学习(推荐):经典书籍《深入理解Java虚拟机 第3版》|第3章 “垃圾收集器与内存分配策略”
10.为什么要分代?怎么判断垃圾?
分析: 上面问题引入话题后,开始延伸细文,所以垃圾回收这块需要重点掌握,系统学习。
参考回答:
Java的垃圾收集采用分代收集的策略,主要是基于弱分代假说和强分代假说这两个理论。 1.弱分代假说认为,绝大多数对象都是朝生夕灭的,即它们很快就会被回收。因此,将这些对象集中在一起,每次回收时只关注如何保留少量存活对象,而不是去标记那些大量将要被回收的对象,可以以较低的代价回收到大量的空间。
2.强分代假说则认为,熬过越多次垃圾收集过程的对象就越难以消亡。因此,将这些难以消亡的对象集中在一起,虚拟机便可以使用较低的频率来回收这个区域,这有助于降低垃圾收集的开销。 综合这两个假说,分代收集策略将Java堆划分为不同的区域,如新生代和老年代,然后将回收对象依据其年龄(即对象熬过垃圾收集过程的次数)分配到不同的区域之中存储。这种设计兼顾了垃圾收集的时间开销和内存的空间有效利用,提高了Java垃圾收集的效率。
1.可达性分析算法:即从根对象(如静态变量、栈中引用等)出发,通过引用链判断哪些对象可达,哪些对象不可达。不可达的对象即为垃圾对象。为了更高效地进行垃圾回收,JVM还采用了标记-清除、标记-复制和标记-整理等算法。标记-清除算法会标记出所有存活对象,然后清除未被标记的垃圾对象;标记-复制算法则将存活对象复制到另一块内存区域,然后整体清除原区域;标记-整理算法则标记存活对象并移动到一端,然后直接清理掉边界以外的内存。这些算法各有优劣,JVM会根据实际情况选择合适的算法进行垃圾回收
2.引用计数算法:是一种简单的垃圾回收算法。它的核心思想是:每个对象都有一个引用计数器,每当有一个地方引用这个对象时,计数器就加1;当引用失效时,计数器就减1。当计数器为0时,表示该对象不再被使用,可以被垃圾回收器回收。然而,引用计数技术无法解决对象之间相互循环引用的问题,因此现代JVM通常不单独使用这种技术,而是与其他算法结合使用。
3.三色标记算法:是一种更复杂的垃圾回收算法,用于解决并发标记时对象引用关系改变的问题。它将对象分为三种颜色:白色表示未被访问过的对象,灰色表示已被访问但其子节点未被全部访问的对象,黑色表示已被访问且其子节点也已被全部访问的对象。在垃圾回收过程中,从根对象出发遍历对象图,将遍历到的对象从白色变为灰色,然后将其子节点标记为灰色或黑色,最终将所有存活的对象标记为黑色。三色标记算法可以有效地处理并发标记时的对象引用关系变化,是现代JVM中常用的垃圾回收算法之一。
学习指引: 1.系统学习(推荐):经典书籍《深入理解Java虚拟机 第3版》|第3章 “垃圾收集器与内存分配策略”|3.3.1 分收集理论 |3.4 HotSpot的算法细节实现
11.了解安全点吗?要是走不到安全点怎么办?
分析: 继续考察JVM垃圾回收相关问题。
参考回答:
安全点:安全点是指在代码执行过程中的一些特殊位置,在这些位置上,JVM可以安全地暂停线程进行垃圾收集,而不会导致应用程序的状态出现不一致。换句话说,安全点是垃圾收集器可以安全地中断线程执行并进行对象图遍历的地方。为了实现安全点,JVM需要在编译时或解释执行时插入一些特殊的指令,这些指令会检查是否需要进入安全点。如果需要,线程将在此处挂起,等待垃圾收集器的工作完成。
安全区域:然而,有时线程可能长时间无法到达安全点,比如在进行一些无法被中断的操作时(如JNI调用)。在这种情况下,如果垃圾收集器需要所有线程都进入安全点,但这些线程却无法到达,就会导致垃圾收集无法进行,进而可能引发应用程序的停顿时间过长或甚至崩溃。为了解决这个问题,JVM引入了"安全区域"的概念。安全区域是指在一段代码执行期间,线程可以在其中任意位置安全挂起的区域。当线程进入安全区域时,它会告知JVM它已经进入了一个安全点。然后,如果垃圾收集器需要所有线程都进入安全点,但它发现有些线程还在安全区域内,它会等待这些线程自行离开安全区域并到达最近的安全点。这样,即使线程在执行一些无法被中断的操作时无法立即进入安全点,只要它们最终能够离开安全区域并到达最近的安全点,垃圾收集器仍然可以完成它的工作。这保证了垃圾收集的正确性和效率,同时也避免了应用程序的长时间停顿或崩溃的风险。
学习指引: 1.系统学习(推荐):经典书籍《深入理解Java虚拟机 第3版》|第3章 “垃圾收集器与内存分配策略”|3.4.2 安全点|3.4.3 安全区域
11.MySQL底层是什么结构,为什么要用b+树,有什么优点
分析: 经典必掌握面试题,mysql索引相关必备知识点,不会的再多看几遍;要掌握B+树与B树,二叉树等之间只对比。变种问题“为什么不用B树,为什么不用二叉树?”
参考回答:
MySQL 默认的存储引擎 InnoDB 采用的是 B+ 作为索引的数据结构,原因有:
- B+ 树的非叶子节点不存放实际的记录数据,仅存放索引,因此数据量相同的情况下,相比存储即存索引又存记录的 B 树,B+树的非叶子节点可以存放更多的索引,因此 B+ 树可以比 B 树更「矮胖」,查询底层节点的磁盘 I/O次数会更少。
- B+ 树有大量的冗余节点(所有非叶子节点都是冗余索引),这些冗余索引让 B+ 树在插入、删除的效率都更高,比如删除根节点的时候,不会像 B 树那样会发生复杂的树的变化;
- B+ 树叶子节点之间用链表连接了起来,有利于范围查询,而 B 树要实现范围查询,因此只能通过树的遍历来完成范围查询,这会涉及多个节点的磁盘 I/O 操作,范围查询效率不如 B+ 树
学习指引:
- 推荐系统学习小林coding 图解Mysql 索引篇,掌握各对比数据结构的特点和差异 资料链接
以上是这位同学一面的面试问题讲解,期望能给大家带来一些帮助。(注意:里面的参考回答不要直接背,尽量系统学习+理解记忆后,用自己的话输出,否则面试你还是答不上来)
后面二面的问题更多是关于该同学个人项目的延伸问题,参考价值不大,就不做分析了。
文中学习指引提到的资料都是公开资料。另外提到的经典书籍,师兄我也有电子版,需要的同学可以点赞+关注后私信我,可免费提供。祝各位找实习/工作一切顺利!
#24届软开秋招面试经验大赏##我发现了面试通关密码##我的实习求职记录##实习,投递多份简历没人回复怎么办##面试经验#挑选近期热门真实后端面经进行讲解分析,给出:个人分析+参考回答+学习资料指引。