Java面试题合集|最常见的网络编程+异常处理面试题!

本文整理了当前热门的Java面试题,重点涵盖网络编程(如IP地址、端口号、TCP与UDP的区别)和异常处理(如OOM错误原因与解决、运行时异常类型、finally执行时机等)。旨在帮助Java开发者更好地理解和应对面试中的网络与异常处理问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

网上的 Java 基础面试题文章有非常多,但是大部分都比较老了。

很多题目早已不是当前的热门题目,没有必要在这些题目上花太多时间。

很多答案放现在已经不准确,可能会误导新人。

因此,我整理了一些时下高频的 Java 基础题目以及Java零基础入门教程,并反复斟酌,给出符合当前版本的解析。

大家也可以直接访问(直接在线观看java最新版的面试题+入门教程):

Java300集零基础适合初学者视频教程_Java300集零基础教程_Java初学入门视频基础巩固教程_Java语言入门到精通

图标

Java考试_Java笔试题机试题真题讲解_JavaWeb阶段考试_Java期末考试通关_Java编程_Java程序员面试题_日常学习

图标

网络编程:

1.IP地址和端口号

1)IP地址

用来标志网络中的一个通信实体的地址。通信实体可以是计算机,路由器等。

2)IP地址分类

IPV4:32位地址,以点分十进制表示,如192.168.0.1

IPV6:128位(16个字节)写成8个16位的无符号整数,每个整数用四个十六进制位表示,数之间用冒号(:)分开,如:3ffe:3201:1401:1280:c8ff:fe4d:db39:1984

3)特殊的IP地址

127.0.0.1 本机地址

192.168.0.0--192.168.255.255私有地址,属于非注册地址,专门为组织机构内部使用。

4)端口:port

IP地址用来标志一台计算机,但是一台计算机上可能提供多种应用程序,使用端口来区分这些应用程序。 端口是虚拟的概念,并不是说在主机上真的有若干个端口。通过端口,可以在一个主机上运行多个网络应用程序。 端口范围0---65535,16位整数

5)端口分类

公认端口 0—1023 比如80端口分配给WWW,21端口分配给FTP,22端口分配给SSH,23端口分配给telnet,25端口分配给smtp

注册端口 1024—49151 分配给用户进程或应用程序

动态/私有端口 49152--65535

6)理解IP和端口的关系

IP地址好比每个人的地址(门牌号),端口好比是房间号。必须同时指定IP地址和端口号才能够正确的发送数据

IP地址好比为电话号码,而端口号就好比为分机号。

2.介绍OSI七层模型和TCP/IP模型

OSI(Open System Interconnection),开放式系统互联参考模型 。是一个逻辑上的定义,一个规范,它把网络协议从逻辑上分为了7层。每一层都有相关、相对应的物理设备,比如常规的路由器是三层交换设备,常规的交换机是二层交换设备。OSI七层模型是一种框架性的设计方法,建立七层模型的主要目的是为解决异种网络互连时所遇到的兼容性问题,其最主要的功能就是帮助不同类型的主机实现数据传输。它的最大优点是将服务、接口和协议这三个概念明确地区分开来,通过七个层次化的结构模型使不同的系统不同的网络之间实现可靠的通讯。

TCP/IP协议是Internet最基本的协议、Internet国际互联网络的基础,主要由网络层的IP协议和传输层的TCP协议组成。TCP/IP 定义了电子设备如何连入因特网,以及数据如何在它们之间传输的标准。协议采用了4层的层级结构,每一层都呼叫它的下一层所提供的协议来完成自己的需求。

ISO制定的OSI参考模型的过于庞大、复杂招致了许多批评。伴随着互联网的流行,其本身所采用的TCP/IP协议栈获得了更为广泛的应用和认可。在TCP/IP参考模型中,去掉了OSI参考模型中的会话层和表示层(这两层的功能被合并到应用层实现)。同时将OSI参考模型中的数据链路层和物理层合并为主机到网络层。

3.TCP协议和UDP协议的比较

TCP和UDP是TCP/IP协议栈中传输层的两个协议,它们使用IP路由功能把数据包发送到目的地,从而为应用程序及应用层协议(包括:HTTP、SMTP、SNMP、FTP和Telnet)提供网络服务。

TCP的server和client之间通信就好比两个人打电话,需要互相知道对方的电话号码,然后开始对话。所以在两者的连接过程中间需要指定端口和地址。

UDP的server和client之间的通信就像两个人互相发信。我只需要知道对方的地址,然后就发信过去。对方是否收到我不知道,也不需要专门对口令似的来建立连接。具体区别如下:

1)TCP是面向连接的传输。UDP是无连接的传输

2)TCP有流量控制、拥塞控制,检验数据数据按序到达,而UDP则相反。

3)TCP的路由选择只发生在建立连接的时候,而UDP的每个报文都要进行路由选择

4)TCP是可靠性传输,他的可靠性是由超时重发机制实现的,而UDP则是不可靠传输

5)UDP因为少了很多控制信息,所以传输速度比TCP速度快

6)TCP适合用于传输大量数据,UDP适合用于传输小量数据

4.什么是Socket编程

Socket编程的定义如下:

所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过"套接字"向网络发出请求或者应答网络请求。

我们开发的网络应用程序位于应用层,TCP和UDP属于传输层协议,在应用层如何使用传输层的服务呢?在应用层和传输层之间,则是使用套接字来进行分离。

套接字就像是传输层为应用层开的一个小口,应用程序通过这个小口向远程发送数据,或者接收远程发来的数据;而这个小口以内,也就是数据进入这个口之后,或者数据从这个口出来之前,是不知道也不需要知道的,也不会关心它如何传输,这属于网络其它层次的工作。

Socket实际是传输层供给应用层的编程接口。传输层则在网络层的基础上提供进程到进程问的逻辑通道,而应用层的进程则利用传输层向另一台主机的某一进程通信。Socket就是应用层与传输层之间的桥梁

使用Socket编程可以开发客户机和服务器应用程序,可以在本地网络上进行通信,也可通过Internet在全球范围内通信。

生活案例1:如果你想写封邮件发给远方的朋友,如何写信、将信打包,属于应用层。信怎么写,怎么打包完全由我们做主;而当我们将信投入邮筒时,邮筒的那个口就是套接字,在进入套接字之后,就是传输层、网络层等(邮局、公路交管或者航线等)其它层次的工作了。我们从来不会去关心信是如何从西安发往北京的,我们只知道写好了投入邮筒就OK了。

生活案例2:可以把Socket比作是一个港口码头,应用程序只要将数据交给Socket,就算完成了数据的发送,具体细节由Socket来完成,细节不必了解。同理,对于接收方,应用程序也要创建一个码头,等待数据的到达,并获取数据。

5.简述基于TCP和UDP的Socket编程的主要步骤

Java分别为TCP和UDP 两种通信协议提供了相应的Socket编程类,这些类存放在java.net包中。与TCP对应的是服务器的ServerSocket和客户端的Socket,与UDP对应的是DatagramSocket。

基于TCP创建的套接字可以叫做流套接字,服务器端相当于一个监听器,用来监听端口。 服务器与客服端之间的通讯都是输入输出流来实现的。基于UDP的套接字就是数据报套接字,• 两个都要先构造好相应的数据包。

基于TCP协议的Socket编程的主要步骤

服务器端(server):

1. 构建一个ServerSocket实例,指定本地的端口。这个socket就是用来监听指定端口的连接请求的。

2. 重复如下几个步骤:

a. 调用socket的accept()方法来获得下面客户端的连接请求。通过accept()方法返回的socket实例,建立了一个和客户端的新连接。

b. 通过这个返回的socket实例获取InputStream和OutputStream,可以通过这两个stream来分别读和写数据。

c. 结束的时候调用socket实例的close()方法关闭socket连接。

客户端(client):

1.构建Socket实例,通过指定的远程服务器地址和端口来建立连接。

2.通过Socket实例包含的InputStream和OutputStream来进行数据的读写。

3.操作结束后调用socket实例的close方法,关闭。

UDP

服务器端(server):

1. 构造DatagramSocket实例,指定本地端口。

2. 通过DatagramSocket实例的receive方法接收DatagramPacket.DatagramPacket中间就包含了通信的内容。

3. 通过DatagramSocket的send和receive方法来收和发DatagramPacket.

客户端(client):

1. 构造DatagramSocket实例。

2. 通过DatagramSocket实例的send和receive方法发送DatagramPacket报文。

3. 结束后,调用DatagramSocket的close方法关闭。

异常处理:

1.下列哪种异常是检查型异常,需要在编写程序时声明()

2.Java出现OutOf MemoryError(OOM 错误)的原因有哪些?出现OOM错误后,怎么解决?

答:OutOf MemoryError这种错误可以细分为多种不同的错误,每种错误都有自身的原因和解决办法,如下所示:

java.lang.OutOfMemoryError: Java heap space

错误原因:此OOM是由于JVM中heap的最大值不满足需要。

解决方法:1) 调高heap的最大值,即-Xmx的值调大。2) 如果你的程序存在内存泄漏,一味的增加heap空间也只是推迟该错误出现的时间而已,所以要检查程序是否存在内存泄漏。

java.lang.OutOfMemoryError: GC overhead limit exceeded

错误原因:此OOM是由于JVM在GC时,对象过多,导致内存溢出,建议调整GC的策略,在一定比例下开始GC而不要使用默认的策略,或者将新代和老代设置合适的大小,需要进行微调存活率。

解决方法:改变GC策略,在老代80%时就是开始GC,并且将-XX:SurvivorRatio(-XX:SurvivorRatio=8)和-XX:NewRatio(-XX:NewRatio=4)设置的更合理。

java.lang.OutOfMemoryError: Java perm space

错误原因:此OOM是由于JVM中perm的最大值不满足需要。

解决方法:调高heap的最大值,即-XX:MaxPermSize的值调大。

另外,注意一点,Perm一般是在JVM启动时加载类进来,如果是JVM运行较长一段时间而不是刚启动后溢出的话,很有可能是由于运行时有类被动态加载进来,此时建议用CMS策略中的类卸载配置。如:-XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled。

java.lang.OutOfMemoryError: unable to create new native thread

错误原因:当JVM向OS请求创建一个新线程时,而OS却由于内存不足无法创建新的native线程。

解决方法:如果JVM内存调的过大或者可利用率小于20%,可以建议将heap及perm的最大值下调,并将线程栈调小,即-Xss调小,如:-Xss128k。

java.lang.OutOfMemoryError: Requested array size exceeds VM limit

错误原因:此类信息表明应用程序(或者被应用程序调用的APIs)试图分配一个大于堆大小的数组。例如,如果应用程序new一个数组对象,大小为512M,但是最大堆大小为256M,因此OutOfMemoryError会抛出,因为数组的大小超过虚拟机的限制。

解决方法:1) 首先检查heap的-Xmx是不是设置的过小。2) 如果heap的-Xmx已经足够大,那么请检查应用程序是不是存在bug,例如:应用程序可能在计算数组的大小时,存在算法错误,导致数组的size很大,从而导致巨大的数组被分配。

java.lang.OutOfMemoryError: request < size> bytes for < reason>. Out of swap space

错误原因:抛出这类错误,是由于从native堆中分配内存失败,并且堆内存可能接近耗尽。这类错误可能跟应用程序没有关系,例如下面两种原因也会导致错误的发生:1) 操作系统配置了较小的交换区。2)系统的另外一个进程正在消耗所有的内存。

解决办法:1) 检查os的swap是不是没有设置或者设置的过小。2) 检查是否有其他进程在消耗大量的内存,从而导致当前的JVM内存不够分配。

注意:虽然有时< reason>部分显示导致OOM的原因,但大多数情况下,< reason>显示的是提示分配失败的源模块的名称,所以有必要查看日志文件,如crash时的hs文件。

3.列举常见的运行时异常

答:ClassCastException(类转换异常)

比如 Object obj=new Object(); String s=(String)obj;

IndexOutOfBoundsException(下标越界异常)

NullPointerException(空指针异常)

ArrayStoreException(数据存储异常,操作数组时类型不一致)

BufferOverflowException(IO操作时出现的缓冲区上溢异常)

InputMismatchException(输入类型不匹配异常)

ArithmeticException(算术异常)

注意:运行时异常都是RuntimeException子类异常。

4.下面关于 Java.lang.Exception类的说法正确的是()

5.Unsupported major.minor version 52是什么异常,怎么造成的,如何解决?

答:问题的根本原因是工程中某个jar包的版本(jar包编译时的所用的jdk版本)高于工程build path中jdk的版本,这个是不兼容的! 编程中遇到此异常Unsupported major.minor version 52.0(根据版本号,这里可以为其他数值,52是1.8jdk jar包与 1.8以下低版本jdk不匹配),在将build path中jdk的版本调整与jar包匹配后,解决异常。

6.try{}里有一个return语句,那么紧跟在这个try后的finally{}里的code会不会被执行,什么时候被执行,在return前还是后?

答:会执行,在方法返回调用者前执行。Java允许在finally中改变返回值的做法是不好的,因为如果存在finally代码块,try中的return语句不会立马返回调用者,而是记录下返回值待finally代码块执行完毕之后再向调用者返回其值,然后如果在finally中修改了返回值,这会对程序造成很大的困扰,C#中就从语法上规定不能做这样的事。

(也许你的答案是在return之前,但往更细地说,我的答案是在return中间执行,请看下面程序代码的运行结果:

执行结果

运行结果是1,为什么呢?主函数调用子函数并得到结果的过程,好比主函数准备一个空罐子,当子函数要返回结果时,先把结果放在罐子里,然后再将程序逻辑返回到主函数。所谓返回,就是子函数说,我不运行了,你主函数继续运行吧,这没什么结果可言,结果是在说这话之前放进罐子里的。

7.Java 语言如何进行异常处理,关键字:throws、throw、try、catch、finally分别如何使用?

答:Java 通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口。在Java 中,每个异常都是一个对象,它是Throwable 类或其子类的实例。当一个方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并进行处理。Java 的异常处理是通过5 个关键词来实现的:try、catch、throw、throws和finally。一般情况下是用try来执行一段程序,如果出现异常,系统会抛出(throw)一个异常,这时候你可以通过它的类型来捕捉(catch)它,或最后(finally)由缺省处理器来处理;try用来指定一块预防所有“异常”的程序;catch 子句紧跟在try块后面,用来指定你想要捕捉的“异常”的类型;throw 语句用来明确地抛出一个“异常”;throws用来标明一个成员函数可能抛出的各种“异常”;finally 为确保一段代码不管发生什么“异常”都被执行一段代码;可以在一个成员函数调用的外面写一个try语句,在这个成员函数内部写另一个try语句保护其他代码。每当遇到一个try 语句,“异常”的框架就放到栈上面,直到所有的try语句都完成。如果下一级的try语句没有对某种“异常”进行处理,栈就会展开,直到遇到有处理这种“异常”的try 语句。

8.运行时异常与受检异常有何异同?

答:异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误,只要程序设计得没有问题通常就不会发生。受检异常跟程序运行的上下文环境有关,即使程序设计无误,仍然可能因使用的问题而引发。Java编译器要求方法必须声明抛出可能发生的受检异常,但是并不要求必须声明抛出未被捕获的运行时异常。异常和继承一样,是面向对象程序设计中经常被滥用的东西,神作《Effective Java》中对异常的使用给出了以下指导原则:

不要将异常处理用于正常的控制流(设计良好的API不应该强迫它的调用者为了正常的控制流而使用异常)

对可以恢复的情况使用受检异常,对编程错误使用运行时异常

避免不必要的使用受检异常(可以通过一些状态检测手段来避免异常发生)

优先使用标准的异常

每个方法抛出的异常都要有文档

保持异常的原子性

不要在catch中忽略掉捕获到的异常

(异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。)

9.类ExampleA 继承Exception,类ExampleB 继承ExampleA

有如下代码片断:

请问执行此段代码的输出是什么?

答:输出:ExampleA。(根据里氏代换原则[能使用父类型的地方一定能使用子类型],抓取ExampleA类型异常的catch块能够抓住try块中抛出的ExampleB类型的异常)

补充: 比此题略复杂的一道面试题如下所示(此题的出处是《Java编程思想》),说出你的答案吧!

输出为:

Caught Annoyance

Caught Sneeze

Hello World!

10.Error和Exception的区别

Error类,表示仅靠程序本身无法恢复的严重错误,比如说内存溢出、动态链接异常、虚拟机错误。应用程序不应该抛出这种类型的对象。假如出现这种错误,除了尽力使程序安全退出外,在其他方面是无能为力的。所以在进行程序设计时,应该更关注Exception类。

Exception类,由Java应用程序抛出和处理的非严重错误,比如所需文件没有找到、零作除数,数组下标越界等。它的各种不同子类分别对应不同类型异常。可分为两类:Checked异常和Runtime异常

11.Java异常处理try-catch-finally的执行过程

try-catch-finally程序块的执行流程以及执行结果比较复杂。

基本执行过程如下:

1)程序首先执行可能发生异常的try语句块。

2)如果try语句没有出现异常则执行完后跳至finally语句块执行;

3)如果try语句出现异常,则中断执行并根据发生的异常类型跳至相应的catch语句块执行处理。

4)catch语句块可以有多个,分别捕获不同类型的异常。

5)catch语句块执行完后程序会继续执行finally语句块。

finally语句是可选的,如果有的话,则不管是否发生异常,finally语句都会被执行。需要注意的是即使try和catch块中存在return语句,finally语句也会执行,是在执行完finally语句后再通过return退出。

12.异常处理中throws和throw的区别

1)作用不同:

throw用于程序员自行产生并抛出异常;

throws用于声明在该方法内抛出了异常

2) 使用的位置不同:

throw位于方法体内部,可以作为单独语句使用;

throws必须跟在方法参数列表的后面,不能单独使用。

3)内容不同:

throw抛出一个异常对象,且只能是一个;

throws后面跟异常类,而且可以有多个。

以上是java面试题集中的网络编程及异常处理面试题整理,需要完整版java面试题集的朋友们,评论区留言或私信,我发给你!

接下来是对各位想要学习java的朋友的一些小小建议,希望对你有帮助!

不管你是学生还是上班族,出了社会才知道钱能挣屎难吃,在学校混日子过来的人,没有一个不后悔的。当你有一天在这个社会生存都成了问题的时候,你会发现自己所有的一切都是灰暗的,穷生奸计富长良心,我体会到了这句话的含义。所以奉劝那些还在上学的学弟(妹)们,抓紧在学校的日子学会一个顺应这个时代发展的技术,选择一个有发展空间的行业,毕业后能找到一份不错的工作,可以让自己有较高的起点,然后不断的向上发展。

下面是我学习Java的一些小心得分享给大家:

1、 千万别自己一个人闭门造车。不要认为自己可以解决所有问题,学习编程很抽象,尤其是在刚开始学的时候,很多时候你是无从下手的,所以我建议大家一定要懂得借力,找一些学的比较好的同学,或者你认识的朋友带带你,有人真的是事半功倍,效率会提高非常多。或者加一些学习氛围不错的Java交流学习群(我这里有),跟有经验的人交流可以学到很多好的学习方法和技巧,提高我们的学习效率。

2、 工欲利其事,必先利其器。在确定了要学习Java前,你一定要有一个非常完整的Java技术栈的大纲体系(比如下面的学习路线图)以及还不错的学习教程,如果我们连一套完整的学习教程都没有,根本不可能学会Java。而很多人在开始时用的教程非常老,很多技术都已经过时,企业并不用这些技术,所以学了也是白耽误工夫。如果大家找不到合适的Java教程,可以试试我推荐的教程,都是免费的,不需要担心。

 Java300集零基础适合初学者视频教程_Java300集零基础教程_Java初学入门视频基础巩固教程_Java语言入门到精通

图标

3、 实践是检验真理的唯一标准。学习编程一定要记得多动手写代码,视频只需要看一两遍即可。有很多同学不懂得如何学习编程,盲目无脑的一直刷视频看,但你看完视频后很快就会忘记,其实是在浪费你的时间。学习编程的主要目的是能做出好的互联网软件产品。这是一个需要动手的工作,所以我们学编程一定要注重动手写代码。而很多人学习编程都是只看视频,这样的学习方式是非常错误的,所以大家对于这点一定要牢记在心。

4、 项目作品是展现我们水平的重要因素。我们在学完一个阶段后,一定要记得针对这个阶段去完成一个项目实战。真正能让我们印象深刻,加深理解的学习方式就是参与到项目的开发中。项目才能检验我们这个阶段到底学的怎么样,所以大家在学习的过程中切记项目的重要性,很多人学习Java最后却不能独立完成一个项目模块,如果你达不到这个水平,那么你是不可能找到Java开发工作的。

史上最全java项目实战课程(含项目实战+源码)

图标

我认为新手在学习Java的过程中常见的误区:

1.没有详细系统的学习规划,越学越迷茫,不知道应该往哪里走,特别有想放弃的想法。

2.学习的技术并不是现在企业需要的技术,跟不上时代,不具备竞争力。

3.学习效率非常低,遇到一个小问题解决起来很费时间,甚至有的时候会卡几个小时,导致信心受挫,对自己适不适合产生怀疑。

4.没有掌握学习Java的方法和技巧,导致走的弯路特别多,钻进程序的死胡同出不来。

如果你也有以上的学习困惑,觉得自己无从下手,学习的效率很低,学了后面就把前面的忘记这些问题,基本都是因为自己的学习方法不对。所以我建议你一定要找有经验的人多沟通,这些问题都是可以得到很好解决的。

几个小技巧大家参考一下:

1、基础很重要,不要盲目的追求新技术,往往决定着你思维深度而又被你忽略的就是你的基础!

2、多动手敲代码,有时电脑就和女(男)朋友一样,它和你想的总是有差异的!

3、多百度,多搜索,百度会帮你解决掉百分之九十以上的问题!

4、多思考,急于动手写代码是大忌,熬夜写代码效率并不高。

最后,希望我的学习经验可以帮助到你,多结交一个圈子内的大佬,方便以后创业,毕竟一辈子给人打工是没有止境的。

文章整理不易,还请各位抬抬您的小贵手,点个赞呗~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值