JAVA面试题

JAVA基础

1、 B/S架构和C/S架构的区别:
B/S架构,即浏览器/服务器架构,B/S系统统一了客户端,无需特殊安装,拥有web浏览器即可。
C/S架构,即客户端/服务器架构,需要安装客户端才可进行管理操作。
2、 面向对象的五大基本原则
单一职责原则SRP(Single Responsibility Principle)
类的功能要单一,不能包罗万象,跟杂货铺似的。
开放封闭原则OCP(Open-Close Principle)
一个模块对于拓展是开放的,对于修改是封闭的,想要增加功能热烈欢迎,想要修改,哼,一万个不乐意。
里式替换原则LSP(the Liskov Substitution Principle LSP)
子类可以替换父类出现在父类能够出现的任何地方。比如你能代表你爸去你姥姥家干活。哈哈~~
依赖倒置原则DIP(the Dependency Inversion Principle DIP)
高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。抽象不应该依赖于具体实现,具体实现应该依赖于抽象。就是你出国要说你是中国人,而不能说你是哪个村子的。比如说中国人是抽象的,下面有具体的xx省,xx市,xx县。你要依赖的抽象是中国人,而不是你是xx村的。
接口分离原则ISP(the Interface Segregation Principle ISP)
设计时采用多个与特定客户类有关的接口比采用一个通用的接口要好。就比如一个手机拥有打电话,看视频,玩游戏等功能,把这几个功能拆分成不同的接口,比在一个接口里要好的多。

3、 JDK和JRE的区别
JDK(java development kit):java开发工具包,包含JRE和java工具
JRE(java runtime environment):java运行环境,包含java基本类库和jvm
4、 equals和==的区别
在object类中,equals和都是比较内存中对象的存储地址,其中比较的是两个数据类型相同的对象,int a = 10;double b = 10.0(true);Integer a = 10;Double b = 10.0(编译错误)
在String等包装类中,重写了equal方法,用于比较对象数值是否相等
5、 假设数组有5个元素,如何对数组进行反序
创建一个新的数组,反向遍历数组,将值依次存入新的数组。
6、 形参和实参的区别
实参:全称为"实际参数"是在调用时传递给函数的参数. 实参可以是常量、变量、表达式、函数等, 无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值, 以便把这些值传送给形参。
形参:全称为"形式参数" 由于它不是实际存在变量,所以又称虚拟变量。是在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数 时传入的参数.在调用函数时,实参将赋值给形参。因而,必须注意实参的个数,类型应与形参一一对应,并且实参必须要有确定的值。 形参出现在函数定义中,在整个函数体内都可以使用,离开该函数则不能使用,函数调用时分配内存,结束后释放内存。
7、 静态内部类和内部类的区别:
静态内部类独立于外界方法,可以直接访问静态变量和静态方法,但在静态内部类中不能直接访问普通方法,只能通过实例化对象的方式访问外部方法和变量。
普通内部类作为外部类一个成员而存在,在普通内部类中可以直接访问外部类属性,调用外部类的方法。
8、 子父类初始化及调用问题:
主动引用:

在这里插入图片描述
在这里插入图片描述

被动引用:
当子类调用父类的静态变量时,子类仅加载,并不会初始化。
在这里插入图片描述

当调用一个final修饰的静态常量时,在编译阶段就已经赋值,不会触发调用常量类的初始化
在这里插入图片描述
在这里插入图片描述

9、static关键字的作用:
static 可以修饰内部类、变量、方法、代码块
static修饰的方法为静态方法,可直接使用类名.调用
static修饰的方法、代码块都只能访问静态变量和方法
static修饰的内容在类加载时在方法区开辟内存,全局共享
10、 final关键字的作用
final修饰的类不能被继承
final修饰的方法不能被重写,但能被继承
final修饰的变量不可被修改,如果修饰的引用变量,地址不遍,引用内容可以改变
final修饰的常量,在编译时写入常量池
11、 java中的继承是多继承还是单继承
java中既有单继承也有多继承,在父类、子类中,子类只可继承一个父类,在接口中,一个接口可以继承多个接口,并且接口只能继承接口。
12、 深复制和浅复制的区别:
浅复制:复制的是引用变量的地址,仅仅复制所考虑的对象, 而不复制它所引用的对象.
深复制:复制的是对象本身,复制的对象所引用的对象都复制了一遍.
13、 java的四种引用,强弱软虚
强引用:在内存不足的时候也不会被回收
弱引用:在内存不足的时候,会被回收
软引用:当垃圾回收器发现它时就会被回收
虚引用:在被回收之前,需要先加入到入ReferenceQueue队列。其余都是先被jvm回收后再加入队列中。
14、 创建对象的几种方式:
通过new创建对象
通过反射机制创建对象
采用clone机制
采用反序列化的机制
15、异常处理:
1、 error和exception有什么区别
error表示系统级的错误,是Java运行环境内部错误或者硬件问题,无法通过程序来解决,它是java虚拟机抛出的。
Exception表示程序需要捕捉和处理的异常,属于程序必须处理的问题。
2、 运行时异常和一般异常有什么区别
一般异常主要是指IO异常、SQL异常等,对于这种异常,jvm要求必须进行try…catch处理,否则会编译报错。
运行时异常,通常会由java虚拟机自动抛出并自动捕获。
3、 Java异常处理机制的原理
Java通过面向对象的方式对异常进行处理,在Java中每个异常都是一个对象,他们都是Throwable或其子类的实例,当一个方法出现异常后就会抛出一个异常对象,该对象包含异常信息,然后通过此对象,输出异常信息。
4、 你平时在项目中是怎样对异常进行处理的。
(1) 尽量避免运行时异常,在使用对象之前,要先进行对象判空操作。
(2) 进行try catch处理的时候要在catch代码块中对异常信息进行记录,将获取到的异常信息返还给前端用户,同时进行日志记录方便后期维护
5、 Final、finally、finalize的区别
Final用于声明变量、方法和类
Finally是异常处理的一个关键字
Finalize是object类的一个方法,在垃圾回收的时候会调用被回收对象的此方法。

16、IO流
1、 java中的流:
按照流的流向可分为:输入流和输出流
按照操作单元可分为:字节流和字符流
按照是否能直接操作数据文件:节点流和处理里流
节点流:可直接在构造方法中传入所传文件对象或文件名
处理流:不能直接在构造方法中传入要读写的文件对象或文件名
2、 Java IO和NIO的区别:
(1)、IO是面向流的,NIO是面向缓冲区的
Java io面向流意味着每次从流中读取一个或多个字节,直至读取所有字节。
Java nio将数据读取到一个它稍后处理的缓冲区,需要时在缓冲区中前后移动
(2)阻塞和非阻塞
Java io流是阻塞的,当一个线程调用read()时,该线程被阻塞,直到一些数据被读取或完全写入
Java nio是非阻塞模式,线程从某通道发出请求读取数据,它只能读取到当前可用数据,如果当前没有可用数据,该线程可以去做其他事情,直到数据变得可以读取。
(3)、java nio引入了选择器,可以使单线程监听多个数据通道,提高了线程处理通道的效率。
3、NIO、BIO 、AIO的区别:

在这里插入图片描述

4、JAVA NIO
Java NIO的三大核心:Channel(通道)、Buffer(缓冲区)、Selector.
传统IO是基于流开发,NIO是基于缓存区开发。数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中
在这里插入图片描述

5、BIO和NIO的读取数据步骤:
BIO:
1、 jvm堆执行fileInputStream.read()请求操作系统,然后操作系统请求磁盘。
2、 从磁盘中读取数据,然后写到操作系统缓存中
3、 将操作系统缓存区的数据放入jvm进程缓存区(按字节,一个字节一个字节的读取)
4、 jvm将jvm缓存区中的数据拷贝到jvm堆中。

在这里插入图片描述

NIO:
1、 NIO以块的形式读取数据
2、 NIO在请求数据时,直接从磁盘将数据映射到jvm进程的地址空间中。
在这里插入图片描述

17、 集合/泛型
1、 ArrayList和LinkedList的区别
ArrayList 是常用的 List 实现类,内部是通过数组实现的,它允许对元素进行快速随机访问。数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就将已经有数组的数据复制到新的存储空间中。
LinkedList 是用链表结构存储数据的,很适合数据的动态插入和删除,随机访问和遍历速度比较慢。另外,他还提供了 List 接口中没有定义的方法,专门用于操作表头和表尾元素,可以当作堆、栈、队列和双向队列使用。
2、 Vector( 数组实现、 线程同步)
Vector 与 ArrayList 一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写 Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此,访问它比访问 ArrayList 慢。
3、 java中的泛型是什么?有什么好处?
泛型是为了防止在运行时出现类型转换错误而导致的ClassCastException异常,引用泛型,在编译时就可确保类型转换的正确性,减少了程序运行时的错误。
4、 Map和Collection是所有集合接口的父接口:
Map:
HashMap、TreeMap、HashTable、ConcurrentHashMap
Collection:
Set和List
Set: HashSet、TreeSet、LinkedHashSet
List: ArrayList、LinkedList、vector、Stack
5、 HashMap和HashTable的区别:
HashMap不考虑线程同步、HashTable加入了synchronized关键字,线程安全。
HashMap的key/value允许都为空,HashTable不允许为空
HashMap继承自AbstractMap类,HashTable继承自Dictionary类;
6、 HashMap的put方法的具体流程?
在这里插入图片描述

7、 HashMap如何解决哈希冲突问题:
1、 使用链地址法(散列表)来连接拥有相同Hash值的数据;
2、 使用2次扰动函数(hashcode右移16位保证高位与地位都可进行按位与计算)来降低hash碰撞的概率;
3、 引用红黑树降低遍历的时间复杂度;
8、 ConcurrentHashMap和Hashtable的区别?
HashMap是线程不同步的,HashTable是线程同步的,却在使用时锁住了所有的结构,ConcurrentHashMap采用了分段锁机制,将数据一段一段存储,然后在锁住一段数据的时候,其余数据依旧可以访问,避免造成了死锁问题。
9、 为什么HashMap中String、Integer这样的包装类适合作为K?
1、都是final类型,即不可变性,保证key的不可更改性,不会存在获取hash值不同的情况
2、内部已重写了equals()、hashCode()等方法,遵守了HashMap内部的规范(不清楚可以去上面看看putValue的过程),不容易出现Hash值计算错误的情况
10、Java集合的快速失败机制 “fail-fast”?
是java集合的一种错误检测机制,当多个线程对集合进行结构上的改变的操作时,有可能会产生 fail-fast 机制。
例如:假设存在两个线程(线程1、线程2),线程1通过Iterator在遍历集合A中的元素,在某个时候线程2修改了集合A的结构(是结构上面的修改,而不是简单的修改集合元素的内容),那么这个时候程序就会抛出 ConcurrentModificationException 异常,从而产生fail-fast机制。
原因:迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个 modCount 变量。集合在被遍历期间如果内容发生变化,就会改变modCount的值。每当迭代器使用hashNext()/next()遍历下一个元素之前,都会检测modCount变量是否为expectedmodCount值,是的话就返回遍历;否则抛出异常,终止遍历。
11、 数组和集合的区别
数组长度是固定的;集合是可变的;
数组只可存储相同数据类型,可存基本数据类型,也可存引用类型;集合只可存引用类型,且可存不同的类型;
12、边遍历集合边删除
在这里插入图片描述

13、遍历一个 List 有哪些不同的方式?每种方法的实现原理是什么?
1、for 循环遍历,基于计数器。在集合外部维护一个计数器,然后依次读取每一个位置的元素,当读取到最后一个元素后停止。
2、迭代器遍历,Iterator 是面向对象的一个设计模式,目的是屏蔽不同数据集合的特点,统一遍历集合的接口。Java 在 Collections 中支持了 Iterator 模式。
3、foreach 循环遍历。foreach 内部也是采用了 Iterator 的方式实现,使用时不需要显式声明 Iterator 或计数器。优点是代码简洁,不易出错;缺点是只能做简单的遍历,不能在遍历过程中操作数据集合,例如删除、替换。
14、map集合遍历
Map<String,String> map = new HashMap<>();
1、 for(String key : map.keySet()){
String key = key;
String value = map.get(key);
}
2、 for(Map.Entry<String,String> entry : map.entrySet()){
String key = entry.getKey();
String value = entry.getValue();
}
3、 Iterator<Map.Entry<String,String>>it=map.entrySet().iterator();
while(it.hasNext()){
Map.Entry<String,String> entry=it.next();
String key=entry.getKey();
String value=entry.getValue();
}
15、String地址传递笔试题
在这里插入图片描述

输出:good

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值