艰难的秋招之路(Java综合面经(计网和基础))

写在前面

对于一名非计算机专业的应届生来说,转行计算机是非常难的。首先说一下自己的情况,独立学院的本科,杭电通信工程学院的硕士。在投简历过程中,暂时并没有太多公司直接简历就让我挂掉,但是心里都清楚,这种第一学历,大多数公司是很嫌弃的,很多学长在分享面经时,也提到第一学历不好就没戏。更何况,还是非计算机专业的,那些《编译原理》、《操作系统》等课程,我是没学过的。再加上今年疫情影响,Java行业人才爆满,也让我的求职之路异常艰辛。

对于Java程序员来说,其实并不是你不优秀,而是竞争的人太多了。首先就是基础要好,如果春招时有大厂的实习offer,那无疑是最大的加分项。其次,像分布式,高并发、框架源码这样的高级Java工程师需要掌握的知识,你校招时就已经会了,那也会增分不少。总的来说:学历+实习+竞赛+项目。下面我就来分享一下,我春招找实习和秋招正式批的面经。其中的答案是自己写的,如果有错误或补充,欢迎留言。
艰难的校招之路(Java综合面经系列)

一、计算机网络

关于计网,之前有一篇博客总结过,下列问题如果没有详细解答,就是在之前博客里有。
博客链接:计算机网络

1.get请求和post请求的区别

2.在浏览器网址输入一个url后直到浏览器显示页面的过程 (可能会问DNS)

DNS:DNS是计算机域名的缩写,它是由解析器和域名服务器组成的。DNS是建立在分布式数据库上的分层命名系统。该系统将域名转换为IP地址,并可以将域名分配给 Internet 组资源和用户,无论实体的物理位置如何。
DNS协议用到了什么传输层协议:TCP和UDP,常用的是UDP。

3.tcp三次握手和四次挥手

4.七层OSI模型或TCP/IP协议模型

艰难的校招之路(Java综合面经系列)

5.各种IO模型的知识

这个可以看我之前的博客:Java之IO

6.http协议和tcp协议的区别

TCP协议对应于传输层,而HTTP协议对应于应用层,从本质上来说,二者没有可比性。Http协议是建立在TCP协议基础之上的应用。

7.https和http的区别

8.https的请求过程

艰难的校招之路(Java综合面经系列)

9.tcp和udp的区别

10.tcp如何实现可靠传输 (如何实现udp的可靠传输)

udp的可靠传输:传输层无法保证数据的可靠传输,只能通过应用层来实现了。实现的方式可以参照tcp可靠性传输的方式,只是实现不在传输层,而是转移到了应用层。

  1. 添加seq/ack机制,确保数据发送到对端
  2. 添加发送和接收缓冲区,主要是用户超时重传。
  3. 添加超时重传机制。

开源程序:RUDP(Reliable User Datagram Protocol)、RTP(Real Time Protocol)、UDT(UDP-based Data Transfer Protocol)

11.http协议的发展历程(1.0,1.1,2.0,3.0)

可以看下这篇博客,讲的很全:http发展
其中http3.0可以看:http3.0

12.ICMP协议的应用

ICMP协议(因特网信息管理协议):在这个协议中提供了对网络状态进行检测的工具,我们可以通过这个协议的工具去收集网络相关的信息。

  1. 通过icmp的ping工具可以帮助我们检测网络中不同节点的IP连通性。ping可以直接ping地址,也可以ping域名。ping得通就说明能收到目标节点的应答。
  2. tracert(traceroute)工具。tracert和traceroute是一样的意思,只是一个常用在华为设备上,一个用在思科设备上。可以跟踪网络中从源节点到目标节点中间所经过的所有三层节点信息。tracert(traceroute)和ping一样可以跟IP和域名。

这两个工具常用于检查连通性和排查故障节点。

13.forward和redirect的区别

  1. 请求方不同
    redirect:客户端发起的请求
    forward:服务端发起的请求
  2. 浏览器地址表现不同
    redirect:浏览器地址显示被请求的url
    forward:浏览器地址不显示被请求的url
  3. 参数传递不同
    redirect:重新开始一个request,原页面的request生命周期结束。
    forward:forward另一个连接的时候。request变量是在其生命周期内的。另一个页面也可以使用,其实质是把目标地址include。
  4. 底层运作不同
    redirect:发送的请求信息又回送给客户机,让客户机再转发到另一个资源上,需要在服务器和客户机之间增加一次通信。
    forward:服务器端直接找到目标,并include过来。
  5. 定义不同
    直接转发方式(Forward):客户端和浏览器只发出一次请求,Servlet、HTML、JSP或其它信息资源,由第二个信息资源响应该请求,在请求对象request中,保存的对象对于每个信息资源是共享的。
    间接转发方式(Redirect)实际是两次HTTP请求,服务器端在响应第一次请求的时候,让浏览器再向另外一个URL发出请求,从而达到转发的目的。

14.丢包、粘包

拆包和粘包可以参考这篇博客:粘包、拆包
关于丢包:TCP本身是确保不丢包的。TCP是基于不可靠的网络实现可靠的传输,肯定也会存在掉包的情况,如果通信中发现缺少数据或者丢包,那么,最大的可能在于程序发送的过程或者接收的过程出现问题。
常用的解决方法有:拆包,加包头,发送组合包

二、Java基础

1.HashMap底层原理

(源码必看!!!必看!!!必看!!!)扩展:jdk1.7和1.8有什么改进?为什么长度大于8转换成红黑树?这个8怎么来的?
这个可以看我之前的博客:Java集合

2.ArrayList底层原理,ArrayList和Vector的区别,LinkedList和ArrayList的区别

这个可以看我之前的博客:Java集合2

3.String,StringBuffer,StringBuilder的区别 扩展:String不可变有什么好处?

口水题。
不可变的好处

  1. 缓存hash值,因为String的hash值会经常用到,比如String做HashMap的key,那么String不可变保证hash值不可变,只需要计算一次,提高计算效率,
  2. String Pool 字符串常量池,一旦字符串String 被创建,下次创建相同的字符串就可以从常量池直接取,也只有当String是不可变才能这样做,
  3. 网络传输安全。String 经常作为参数,String 不可变性可以保证参数不可变。例如在作为网络连接参数的情况下如果 String 是可变的,那么在网络连接过程中,String 被改变,改变 String 对象的那一方以为现在连接的是其它主机,而实际情况却不一定是。
  4. 线程安全 。String是不可变的,保证了线程的安全。

4.jvm相关

jvm内存模型 (线程私有和线程共享内存分别是什么)

gc算法,垃圾收集器有哪些

年轻代出现OOM怎么处理?老年代出现OOM怎么处理?方法区出现OOM怎么处理?本地方法栈出现OOM怎么处理? (反向思考,如何让这些分区OOM)扩展:线上OOM怎么排查问题

jvm类加载过程

java的四种引用类型?jvm如何判断这个对象可回收?finalize方法的作用?

5.java中的锁

synchronized锁膨胀过程

1、整个膨胀过程在自旋下完成;

2、mark->has_monitor()方法判断当前是否为重量级锁,即Mark Word的锁标识位为 10,如果当前状态为重量级锁,执行步骤(3),否则执行步骤(4);

3、mark->monitor()方法获取指向ObjectMonitor的指针,并返回,说明膨胀过程已经完成;

4、如果当前锁处于膨胀中,说明该锁正在被其它线程执行膨胀操作,则当前线程就进行自旋等待锁膨胀完成,这里需要注意一点,虽然是自旋操作,但不会一直占用cpu资源,每隔一段时间会通过os::NakedYield方法放弃cpu资源,或通过park方法挂起;如果其他线程完成锁的膨胀操作,则退出自旋并返回;

5、如果当前是轻量级锁状态,即锁标识位为 00,膨胀过程如下:

  • 通过omAlloc方法,获取一个可用的ObjectMonitor monitor,并重置monitor数据;
  • 通过CAS尝试将Mark Word设置为markOopDesc:INFLATING,标识当前锁正在膨胀中,如果CAS失败,说明同一时刻其它线程已经将Mark Word设置为markOopDesc:INFLATING,当前线程进行自旋等待膨胀完成;
  • 如果CAS成功,设置monitor的各个字段:_header、_owner和_object等,并返回;

6、如果是无锁,重置监视器值;

Java中有哪些锁

乐观锁,悲观锁
共享锁,排他锁(读锁,写锁)
可重入锁,非可重入锁
公平锁,非公平锁

synchronized和lock有什么区别

  1. 两者都是可重⼊锁
  2. synchronized 依赖于 JVM 而 ReentrantLock 依赖于 API
  3. ReentrantLock 比 synchronized 增加了⼀些高级功能:①等待可中断;②可实现公平锁;③可实现选择性通知(锁可以绑定多个条件)

可重入锁和非可重入锁的区别

sleep和wait的区别

sleep是Thread的方法,wait是Object的方法。
sleep()不会释放对象锁。

6.ConcurrentHashMap的底层数据结构

线程安全,主要是因为CAS和sync。

7.volatile的作用

保证可见性,禁止指令重拍(内存屏障)。但不保证原子性。

8.迭代器是做什么的?迭代器的fail-fast机制了解吗?主要为了解决什么问题?

集合的for循环。快速失败机制。集合在迭代时,其他线程有修改操作,会抛并发修改异常。

9.线程池的七个参数,线程池的好处

7个参数,分别是corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler。
艰难的校招之路(Java综合面经系列)
handler有四种:

  1. CallerRunsPolicy
    在调用者线程中直接执行被拒绝任务的run方法,除非线程池已经shutdown,则直接抛弃任务。
  2. AbortPolicy
    直接丢弃任务,并抛出RejectedExecutionException异常。
  3. DiscardPolicy
    直接丢弃任务,什么都不做。
  4. DiscardOldestPolicy
    抛弃进入队列最早的那个任务,然后尝试把这次拒绝的任务放入队列。

好处

  • 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
  • 提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行。
  • 提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统⼀的分配,调优和监控。

10.反射的原理,有什么应用

可以看我的博客:反射

11.线程间如何通信

  1. 使用同一个共享变量控制(sync,wait.notify)
  2. 管道通信,java.io.PipedInputStream 和 java.io.PipedOutputStream
  3. 阻塞队列

12.CAS算法以及可能产生的问题

CAS:Compare and Swap,即比较并交换。利用循环代替了阻塞。底层unsafe类
出现的问题

  1. 循环时间长开销很大。
  2. 只能保证一个变量的原子操作。
  3. ABA问题。(可以加乐观锁解决。)

13.抽象类与接口的区别

14.谈谈对面向对象,多态的理解

面向对象7大原则:
一,单一职责原则(类)

单一职责原则的英文名称是Single Responsibility Principle,简称SRP。它的定义是:就一个类而言,应该仅有一个引起它变化的原因。简单来说,一个类中应该是一组相关性很高的函数、数据的封装。

二,开闭原则(类、模块、函数等)

开闭原则的英文全称是Open Close Principle,简称OCP,它是Java世界里最基础的设计原则,它指导我们如何建立一个稳定的、灵活的系统。开闭原则的定义是:软件中的对象(类、模块、函数等)应该对于扩展是开放的,但是,对于修改是封闭的。

三,里氏替换原则(参数)

里氏替换原则英文全称是Liskov Substitution Principle,简称LSP。我们知道,面向对象的语言的三大特点是继承、封装、多态,里氏替换原则就是依赖于继承、多态这两大特性。里氏替换原则简单来说就是,所有引用基类的地方必须能透明地使用其子类的对象。

四,依赖倒置原则(接口)

依赖倒置原则英文全称是Dependence Inversion Principle,简称DIP。依赖反转原则指代了一种特定的解耦形式,高层模块不依赖低层次模块的细节,说白了高层次就是不依赖细节而是依赖抽象。

五,接口隔离原则(接口)

接口隔离原则英文全称是InterfaceSegregation Principles,简称ISP。它的定义是:客户端不应该依赖它不需要的接口。另一种定义是:类间的依赖关系应该建立在最小的接口上。

六,最少知识原则(类与类的关系)

最少知识原则又称为迪米特原则英文全称为Law of Demeter,简称LOD,虽然名字不同,但描述的是同一个原则:一个对象应该对其他对象有最少的了解。

七.组合/聚合复用原则

合成/聚合复用原则经常又叫做合成复用原则。该原则就是在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分:新的对象通过向这些对象的委派达到复用已有功能的目的

15.常用的设计模式

这个可能会和Spring中AOP一起问,问你AOP涉及哪些设计模式。

  • 代理模式
  • 适配器模式
  • 单例模式
  • 责任链模式
  • 工厂模式
  • 装饰器模式
  • 观察者模式

16.AQS

AbstractQueuedSynchronizer,它提供了一种实现阻塞锁和一系列依赖FIFO双向队列的同步器的框架,ReentrantLock、Semaphore、CountDownLatch、CyclicBarrier等并发类均是基于AQS来实现的,具体用法是通过继承AQS实现其模板方法,然后将子类作为同步组件的内部类。

最后

不知不觉已经这么多了,这篇博客就到这吧。Java基础里还有异常等知识,这都是必须的。未来再写数据库,框架等面经。

相关文章:

  • 2021-07-07
  • 2021-08-11
  • 2022-12-23
  • 2021-11-07
  • 2021-12-05
  • 2021-11-05
猜你喜欢
  • 2022-12-23
  • 2021-11-16
  • 2021-11-11
  • 2022-01-29
  • 2021-12-01
  • 2022-12-23
  • 2021-12-02
相关资源
相似解决方案