温故而知新-Java基础篇【面试复习】

温故而知新-Java基础篇【面试复习】

  • 前言
  • 版权
  • 推荐
  • 温故而知新-基础篇【面试】
    • 解决hash冲突的方法
    • try catch finally
    • Exception与Error的包结构
    • OOM你遇到过哪些情况,SOF你遇到过哪些情况
    • 线程有哪些基本状态?
    • Java IO与 NIO的区别
    • 堆和栈的区别
    • 对象分配规则
    • notify()和notifyAll()有什么区别?
    • sleep()和wait() 有什么区别?
    • 为什么wait, notify 和 notifyAll这些方法不在thread类里面?
    • Java中synchronized 和 ReentrantLock 有什么不同?
    • 常用的线程池有哪些?
    • 简述一下你对线程池的理解
    • 反射
  • 最后

前言

2023-7-22 18:56:52

以下内容源自《【面试复习】》
仅供学习交流使用

版权

禁止其他平台发布时删除以下此话
本文首次发布于CSDN平台
作者是CSDN@日星月云
博客主页是https://blog.csdn.net/qq_51625007
禁止其他平台发布时删除以上此话

推荐

温故而知新-基础篇【面试】

解决hash冲突的方法

数据结构中介绍的两种方法:

第八章 查找【数据结构】:8.4.2处理冲突的方法

1.开放定址法
开放定址法也被称为“再散列法”。其基本思想是,当关键字key的初始散列地址h0=H(key)出现冲突时,以h0为基础查找下一个地址h1,如果h1仍然冲突,再以h0为基础,产生另一个散列地址h2…直到找出一个不冲突的地址hi,将相应元素存入其中。这种方法有一个通用的再散列函数形式:
hi=(H(key)+di)%m i=1,2,…,n
其中,H(key)为哈希函数,h,=H(key),m为表长,di为增量序列。增量序列的取值方式不同,对应有不同的再散列方式,主要有以下三种。
(1)线性探测再散列
di=c×i 最简单的情况c=1
这种方法的特点是,冲突发生时,顺序查看表中下一个单元,直到找到一个空单元或查遍全表。值得注意的是,由于这里使用的是%运算,因而整个表成为一个首尾连接的循环表,在查找时类似于循环队列,表尾的后边是表头,表头的前边是表尾。

(2)二次探测再散列
di=12,-12,22,-22,…k2,-k2(k≤m/2)
这种方法的特点是,冲突发生时分别在表的右、左进行跳跃式探测,较为灵话,不易产生聚集,但缺点是不能探查到整个散列地址空间。

(3)随机探测再散列
di=伪随机数
这种方法需要建立一个随机数发生器,并给定一个随机数作为起始点。

2.链地址法
链地址法解决冲突的基本思想是,把所有具有地址冲突的关键字链在同一个单链表中: 若哈希表的长度为m,则可将哈希表定义为一个由m个头指针组成的指针数组。散列地址为i的记录均插入以指针数组第i个单元为头指针的单链表。

Java面试复习发现有第3种方法

3.再哈希法
再哈希:又叫双哈希法,有多个不同的Hash函数.当发生冲突时,使用第二个,第三个….等哈希函数计算地址,直到无冲突

网上又搜了一下发现有第4种方法
hash冲突的4种解决方案
4.建立公共溢出区
将哈希表分为基本表和溢出表两部分,凡是和基本表发生冲突的元素,一律填入溢出表。

try catch finally

finally语句包含return的情况

//下面是个测试程序
public class FinallyTest  
{
	public static void main(String[] args) {
		 
		System.out.println(new FinallyTest().test());;
	}

	static int test()
	{
		int x = 1;
		try
		{
			x++;
			return x;
		}
		finally
		{
			++x;
		}
	}
}
结果是2。
分析:
	在try语句中,在执行return语句时,要返回的结果已经准备好了,就在此时,程序转到finally执行了。
在转去之前,try中先把要返回的结果存放到不同于x的局部变量中去,执行完finally之后,在从中取出返回结果,
因此,即使finally中对变量x进行了改变,但是不会影响返回结果。
它应该使用栈保存返回值。

Exception与Error的包结构

Java可抛出(Throwable)的结构分为三种类型:被检查的异常(CheckedException),运行时异常(RuntimeException),错误(Error)。

1、运行时异常
定义:RuntimeException及其子类都被称为运行时异常。

特点:Java编译器不会检查它。也就是说,当程序中可能出现这类异常时,倘若既"没有通过throws声明抛出它",也"没有用try-catch语句捕获它",还是会编译通过。

例如:除数为零时产生的ArithmeticException异常,数组越界时产生的IndexOutOfBoundsException异常,fail-fast机制产生的ConcurrentModificationException异常

常见的五种运行时异常:
ClassCastException(类转换异常)
IndexOutOfBoundsException(数组越界)
NullPointerException(空指针异常)
ArrayStoreException(数据存储异常,操作数组是类型不一致)
BufferOverflowException(文件流Buffer需要clear)

2、被检查异常
定义:Exception类本身,以及Exception的子类中除了"运行时异常"之外的其它子类都属于被检查异常。
特点 : Java编译器会检查它。 此类异常,要么通过throws进行声明抛出,要么通过try-catch进行捕获处理,否则不能通过编译。

例如,CloneNotSupportedException就属于被检查异常。当通过clone()接口去克隆一个对象,而该对象对应的类没有实现Cloneable接口,就会抛出CloneNotSupportedException异常。被检查异常通常都是可以恢复的。

如:
IOException
FileNotFoundException
SQLException

被检查的异常适用于那些不是因程序引起的错误情况,比如:读取文件时文件不存在引发的FileNotFoundException 。
然而,不被检查的异常通常都是由于糟糕的编程引起的,比如:在对象引用时没有确保对象非空而引起的 NullPointerException 。

3、错误
定义 : Error类及其子类。
特点 : 和运行时异常一样,编译器也不会对错误进行检查。
当资源不足、约束失败、或是其它程序无法继续运行的条件发生时,就产生错误。程序本身无法修复这些错误的。例如,VirtualMachineError就属于错误。出现这种错误会导致程序终止运行。
OutOfMemoryError、ThreadDeath。
Java虚拟机规范规定JVM的内存分为了好几块,比如堆,栈,程序计数器,方法区等

OOM你遇到过哪些情况,SOF你遇到过哪些情况

OOM:

1,OutOfMemoryError异常
除了程序计数器外,虚拟机内存的其他几个运行时区域都有发生OutOfMemoryError(OOM)异常的可能。

Java Heap 溢出:
一般的异常信息:java.lang.OutOfMemoryError:Java heap spacess。java堆用于存储对象实例,我们只要不断的创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,就会在对象数量达到最大堆容量限制后产生内存溢出异常。

出现这种异常,一般手段是先通过内存映像分析工具(如Eclipse Memory Analyzer)对dump出来的堆转存快照进行分析,重点是确认内存中的对象是否是必要的,先分清是因为内存泄漏(Memory Leak)还是内存溢出(Memory Overflow)。

如果是内存泄漏,可进一步通过工具查看泄漏对象到GCRoots的引用链。于是就能找到泄漏对象是通过怎样的路径与GC Roots相关联并导致垃圾收集器无法自动回收。

如果不存在泄漏,那就应该检查虚拟机的参数(-Xmx与-Xms)的设置是否适当。

2,虚拟机栈和本地方法栈溢出
如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。

如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常
意思是没有到达最大深度,但是因内存空间不足二申请不到了

这里需要注意当栈的大小越大可分配的线程数就越少。

3,运行时常量池溢出
异常信息:java.lang.OutOfMemoryError:PermGenspace

如果要向运行时常量池中添加内容,最简单的做法就是使用String.intern()这个Native方法。该方法的作用是:如果池中已经包含一个等于此String的字符串,则返回代表池中这个字符串的String对象;否则,将此String对象包含的字符串添加到常量池中,并且返回此String对象的引用。由于常量池分配在方法区内,我们可以通过-XX:PermSize和-XX:MaxPermSize限制方法区的大小,从而间接限制其中常量池的容量。

4,方法区溢出
方法区用于存放Class的相关信息,如类名、访问修饰符、常量池、字段描述、方法描述等。也有可能是方法区中保存的class对象没有被及时回收掉或者class信息占用的内存超过了我们配置。

异常信息:java.lang.OutOfMemoryError:PermGenspace

方法区溢出也是一种常见的内存溢出异常,一个类如果要被垃圾收集器回收,判定条件是很苛刻的。在经常动态生成大量Class的应用中,要特别注意这点。

SOF(堆栈溢出StackOverflow):
StackOverflowError 的定义:当应用程序递归太深而发生堆栈溢出时,抛出该错误。

因为栈一般默认为1-2m,一旦出现死循环或者是大量的递归调用,在不断的压栈过程中,造成栈容量超过1m而导致溢出。

栈溢出的原因:递归调用,大量循环或死循环,全局变量是否过多,数组、List、map数据过大。

线程有哪些基本状态?

在这里插入图片描述
操作系统隐藏 Java虚拟机(JVM)中的 RUNNABLE 和 RUNNING 状态,它只能看到 RUNNABLE 状态(图源:HowToDoInJava:Java Thread Life Cycle and Thread States),所以 Java 系统一般将这两个状态统称为 RUNNABLE(运行中) 状态 。

Java IO与 NIO的区别

推荐阅读:
什么是NIO?NIO的原理是什么机制?

堆和栈的区别

栈是运行时单位,代表着逻辑,内含基本数据类型和堆中对象引用,所在区域连续,没有碎片;
堆是存储单位,代表着数据,可被多个栈共享(包括成员中基本数据类型、引用和引用对象),所在区域不连续,会有碎片。

1、功能不同
栈内存用来存储局部变量和方法调用,而堆内存用来存储Java中的对象。无论是成员变量,局部变量,还是类变量,它们指向的对象都存储在堆内存中。

2、共享性不同
Young Generation 即图中的Eden + From Space(s0) + To Space(s1)
Eden 存放新生的对象
Survivor Space 有两个,存放每次垃圾回收后存活的对象(s0+s1)
Old Generation Tenured Generation 即图中的Old Space
主要存放应用程序中生命周期长的存活对象

栈内存是线程私有的。
堆内存是所有线程共有的。

3、异常错误不同
如果栈内存或者堆内存不足都会抛出异常。
栈空间不足:java.lang.StackOverFlowError。
堆空间不足:java.lang.OutOfMemoryError。

4、空间大小
栈的空间大小远远小于堆的

对象分配规则

  • 对象优先分配在Eden区,如果Eden区没有足够的空间时,虚拟机执行一次Minor GC。
  • 大对象直接进入老年代(大对象是指需要大量连续内存空间的对象)。这样做的目的是避免在Eden区和两个Survivor区之间发生大量的内存拷贝(新生代采用复制算法收集内存)。
  • 长期存活的对象进入老年代。虚拟机为每个对象定义了一个年龄计数器,如果对象经过了1次Minor GC那么对象会进入Survivor区,之后每经过一次Minor GC那么对象的年龄加1,知道达到阀值对象进入老年区。
  • 动态判断对象的年龄。如果Survivor区中相同年龄的所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象可以直接进入老年代。
  • 空间分配担保。每次进行Minor GC时,JVM会计算Survivor区移至老年区的对象的平均大小,如果这个值大于老年区的剩余值大小则进行一次Full GC,如果小于检查HandlePromotionFailure设置,如果true则只进行Monitor GC,如果false则进行Full GC。

notify()和notifyAll()有什么区别?

notify可能会导致死锁,而notifyAll则不会

任何时候只有一个线程可以获得锁,也就是说只有一个线程可以运行synchronized 中的代码

使用notifyall,可以唤醒所有处于wait状态的线程,使其重新进入锁的争夺队列中,而notify只能唤醒一个

举例:如果是生产者-消费者模型,生产者.notify了一个生产者,就会产生死锁

sleep()和wait() 有什么区别?

对于sleep()方法,我们首先要知道该方法是属于Thread类中的。而wait()方法,则是属于Object类中的。

sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。在调用sleep()方法的过程中,线程不会释放对象锁。

当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备,获取对象锁进入运行状态。

为什么wait, notify 和 notifyAll这些方法不在thread类里面?

明显的原因是JAVA提供的锁是对象级的而不是线程级的,每个对象都有锁,通过线程获得。如果线程需
要等待某些锁那么调用对象中的wait()方法就有意义了。如果wait()方法定义在Thread类中,线程正在
等待的是哪个锁就不明显了。简单的说,由于wait,notify和notifyAll都是锁级别的操作,所以把他们
定义在Object类中因为锁属于对象。

Java中synchronized 和 ReentrantLock 有什么不同?

相似点:
这两种同步方式有很多相似之处,它们都是加锁方式同步,而且都是阻塞式的同步,也就是说当如果一
个线程获得了对象锁,进入了同步块,其他访问该同步块的线程都必须阻塞在同步块外面等待,而进行
线程阻塞和唤醒的代价是比较高的.

区别:

这两种方式最大区别就是对于Synchronized来说,它是java语言的关键字,是原生语法层面的互斥,需
要jvm实现。而ReentrantLock它是JDK 1.5之后提供的API层面的互斥锁,需要lock()和unlock()方法配
合try/finally语句块来完成。

Synchronized进过编译,会在同步块的前后分别形成monitorenter和monitorexit这个两个字节码指
令。在执行monitorenter指令时,首先要尝试获取对象锁。如果这个对象没被锁定,或者当前线程已经
拥有了那个对象锁,把锁的计算器加1,相应的,在执行monitorexit指令时会将锁计算器就减1,当计
算器为0时,锁就被释放了。如果获取对象锁失败,那当前线程就要阻塞,直到对象锁被另一个线程释
放为止。

由于ReentrantLock是java.util.concurrent包下提供的一套互斥锁,相比Synchronized,
ReentrantLock类提供了一些高级功能,主要有以下3项:
1.等待可中断,持有锁的线程长期不释放的时候,正在等待的线程可以选择放弃等待,这相当于
Synchronized来说可以避免出现死锁的情况。
2.公平锁,多个线程等待同一个锁时,必须按照申请锁的时间顺序获得锁,Synchronized锁非公平锁,
ReentrantLock默认的构造函数是创建的非公平锁,可以通过参数true设为公平锁,但公平锁表现的性
能不是很好。
3.锁绑定多个条件,一个ReentrantLock对象可以同时绑定对个对象。

常用的线程池有哪些?

newSingleThreadExecutor:创建一个单线程的线程池,此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
newFixedThreadPool:创建固定大小的线程池,每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。
newCachedThreadPool:创建一个可缓存的线程池,此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。
newScheduledThreadPool:创建一个大小无限的线程池,此线程池支持定时以及周期性执行任务的需求。
newSingleThreadExecutor:创建一个单线程的线程池。此线程池支持定时以及周期性执行任务的需求。

简述一下你对线程池的理解

(如果问到了这样的问题,可以展开的说一下线程池如何用、线程池的好处、线程池的启动策略)合理利用线程池能够带来三个好处。
第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
第三:提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

反射

在ArrayList中的构造器中
有个构造包含指定集合的元素的列表
使用到getClass()方法
在这里插入图片描述

最后

2023-7-25 08:11:35

我们都有光明的未来

祝大家考研上岸
祝大家工作顺利
祝大家得偿所愿
祝大家如愿以偿
点赞收藏关注哦

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/634750.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

安装ollama并部署大模型并测试

Ollama介绍 项目地址:ollama 官网地址: https://ollama.com 模型仓库:https://ollama.com/library API接口:api接口 Ollama 是一个基于 Go 语言开发的简单易用的本地大语言模型运行框架。可以将其类比为 docker(同基…

CCF20220901——如此编码

CCF20220901——如此编码 代码如下&#xff1a; #include<bits/stdc.h> using namespace std; int main() {int n,m,cnt1,a[1000],c[1000]{1};cin>>n>>m;for(int i1;i<n;i){cin>>a[i];cnt*a[i];c[i]cnt;}int b[1000]{0};for(int i1;i<n;i)b[i](…

ESP32学习笔记:WS2812B驱动

WS2812B是一款贴片RGB灯。由于采用了单总线通讯&#xff0c;所以需要特别关注下它的通讯时序。 调试细节&#xff1a; 本来以为会是一个比较简单的调试&#xff0c;结果还是花了很长时间才调试完成。 首先是关于ESP32的纳秒级延时确定&#xff0c;当时按照空指令始终调试不出来…

springboot中使用spring-cloud-starter-openfeign遇到的问题及解决参考

声明&#xff1a;本文使用的spring boot 版本是2.7.12 在springboot中使用spring-cloud-starter-openfeign遇到的一些问题&#xff1a; Caused by: java.lang.ClassNotFoundException: org.springframework.boot.context.properties.ConfigurationBeanFactoryMetadata java.…

webpack打包配置项

webpack打包配置项 在config.js 中 module.exports {publicPath: process.env.NODE_ENV production ? / : /, //静态资源目录outputDir: dist, //打包名称assetsDir: static,//静态资源&#xff0c;目录devServer: {port: port,open: false,overlay: {warnings: false,erro…

如何远程连接默认端口?

远程连接是指通过网络实现两个或多个计算机之间的连接和通信。在进行远程连接时&#xff0c;使用的端口号是一个重要的参数。端口号是计算机上正在运行的特定应用程序的标识符。每个应用程序都会监听一个或多个特定的端口号&#xff0c;以便接收来自其他计算机的连接请求&#…

Docker(四) 文件和网络

1 Dockerfile 1.1 什么是Dockerfile Dockerfile是一个文本文件&#xff0c;包含一系列命令&#xff0c;这些命令用于在 Docker 镜像中自动执行操作。Dockerfile 定义了如何构建 Docker 镜像的步骤和所需的操作。 Dockerfile 中包含的命令可以设置和定制容器的环境&#xff0c;…

满足a==1a==2

网上看到的一道JS面试题&#xff0c;觉得很有意思 觉得很有意思的原因是&#xff0c;这个式子乍看之下是有些反常识的。“a1&&a2”&#xff0c;它的意思似乎是“a在等于1的同时又等于2”&#xff0c;这时我们的第一反应可能就是不成立&#xff0c;一个变量怎么可能同时…

win10编译openssl

环境 Win10 64位 VS2022 openssl 3.3.0 nasm NASM version 2.16.01 compiled on Dec 21 2022 perl strawberry-5.38.2.2环境变量设置 perl加入到环境变量&#xff0c;略过nasm加入到环境变量vs的nmake加入到环境变量我的nmake位置如下&#xff1a; C:\Program…

kubeadm部署k8s v1.28

一、主机准备 主机硬件配置说明 作用IP地址操作系统配置k8s-master01192.168.136.55openEuler-22.03-LTS-SP12颗CPU 4G内存 50G硬盘k8s-node01192.168.136.56openEuler-22.03-LTS-SP12颗CPU 4G内存 50G硬盘k8s-node02192.168.136.57openEuler-22.03-LTS-SP12颗CPU 4G内存 50G…

Gitee在已有项目基础上创建仓库中遇到的问题和解决

问题一&#xff1a;fatal: remote origin already exists 解释&#xff1a;当前仓库添加了一个名为"origin"的远程仓库配置&#xff0c;此时输入 git remote add origin https://xxx就会提示上面的内容。 解决方案1:移除旧的origin git remote remove origin 解决方案…

QTextEdit 控件上显示信息:

目录 1. 使用 append 方法: 2. 使用 setPlainText 方法 3.例子&#xff1a; 1. 使用 append 方法: 如果你希望在 QTextEdit 控件上追加显示新的信息&#xff0c;可以使用 append 方法。例如&#xff0c;当你想要追加一行新的日志信息&#xff1a; self.text_edit.append(&…

金融信贷风控基础知识

一、所谓风控(What && Why) 所谓风控&#xff0c;可以拆解从2个方面看&#xff0c;即 风险和控制 风险(what) 风险 这里狭隘的特指互联网产品中存在的风险点&#xff0c;例如 账户风险 垃圾注册账号账号被泄露盗用 交易支付风险 刷单&#xff1a;为提升卖家店铺人气…

大模型难落地?聊聊大模型在智能财务应用的正确打开方式

大模型难落地&#xff1f;No&#xff0c;是你还不够了解它&#xff01; &#xff08;全文4989字&#xff0c;阅读约需10分钟&#xff09; 这两天&#xff0c;大模型几乎成了WAIC&#xff08;世界人工智能大会&#xff09;的唯一主题。大会上&#xff0c;各家企业的大模型悉数…

深度学习之基于Tensorflow模版匹配智慧停车计费系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 随着城市化进程的加快&#xff0c;停车难问题日益凸显。传统的停车管理方式已经无法满足现代社会的需…

QT7_视频知识点笔记_5_线程,数据库

多线程 两种办法&#xff1a;第一种&#xff1a;Qt4.7之前的线程使用的方法&#xff08;简单&#xff09;&#xff1b;第二种&#xff1a;Qt4.7之后的&#xff08;灵活–推荐&#xff09;----connect最后一个参数的作用&#xff1a;默认连接&#xff0c;队列连接&#xff0c;直…

Linux软硬链接及动静态库

软硬链接与动静态库 软连接 创建链接的方法&#xff1a; ln -s test1.txt test2.txt 其中ln 是link(链接)&#xff0c;-s 是soft(软)&#xff0c;后者链接前者。 此时打开test2.txt&#xff0c;发现其中内容与test.txt一致。那么软连接到底建立了什么联系&#xff1f;…

【笔记】软件架构师要点记录(2)

【笔记】软件架构师要点记录 20240523案例一案例二案例三案例四案例五案例六案例七案例十 20240523 基于前10个架构案例场景&#xff0c;对用到的专业术语进行整理&#xff0c;方便后续查看。 案例一 MVC架构风格组件交互方式 MVC是一种用来构建用户界面时采用的架构设计风格…

分布式Id/框架/发号器一文介绍

文章目录 一、分布式id介绍1、什么是分布式id2、分布式id的特点 二、UUid生成算法1、JDK UUID2、Snowflake 雪花算法3、PearFlower 梨花算法4、Mist 薄雾算法 三、常见发号器服务1、数据库1&#xff09;自增2&#xff09;号段模式 2、NoSQL 四、常见框架1、百度UIDGenerator2、…

基于BERT的中文情感分析实战

数据与代码链接见文末 bert开源项目解读:谷歌开源项目BERT源码解读与应用实例-CSDN博客 基于BERT的中文命名实体识别识别实战:基于BERT的中文命名实体识别识别实战-CSDN博客 1.数据 在data目录下,提供了中文情感分析的数据, 类别1代表正向情感,类别2代表负向情感。