2024面试offer收割宝典字节篇
1.IO 模型有哪些,讲讲你理解的 nio ,他和 bio,aio 的区别是啥, 谈谈 reactor 模型。
IO 模型主要包括以下几种:
1. 阻塞 I/O (BIO):
- 当一个线程调用 read() 或 write() 系统调用时,如果数据没有准备好或者缓冲区已满,则该线程会被操作系统阻塞,直到有数据可读或写入完成。
- 在Java中传统的java.io包中的类如Socket和ServerSocket就是基于BIO模型实现的。
2. 非阻塞 I/O (NIO):
- Java NIO(New Input/Output)在Java 1.4版本引入,提供了非阻塞的I/O能力。
- 使用NIO,当调用channel.read()或channel.write()方法时,若当前无数据可读或缓冲区满不能立即写入,不会阻塞线程,而是会返回一个状态值(通常是0,表示没有数据可读或没有足够的空间写入)。
- NIO支持单线程处理多个Channel(通道),通过Selector可以监听多个Channel的事件,一旦某个Channel准备就绪进行读写操作,Selector就会通知相应的线程去处理。
- NIO的核心组件包括Buffer(缓冲区)、Channel(通道)和Selector(选择器)。
3. 异步 I/O (AIO, NIO.2 或 AIO in Java):
- 异步非阻塞I/O在Java 7中引入,也被称为NIO.2。
- 在AIO模式下,当发起一个读写请求后,应用程序可以继续执行其他任务,而无需等待操作结果。
- 当数据准备完毕或操作完成时,操作系统会回调预先注册的CompletionHandler(完成处理器)来处理数据或处理完成后的逻辑。
- 这种模型极大地提高了系统并发处理能力和资源利用率,特别适合于高并发、低延迟的应用场景。
Reactor 模型是一种设计模式,常用于处理大量并发I/O请求。它通常配合NIO或AIO使用,在服务器端能够同时监听多个连接请求,并且根据不同的事件类型分发给相应的处理器进行处理。基本结构包括:
- Dispatcher:负责监听并分发事件到对应的Handler。
- Handlers:处理实际的I/O事件,如读取数据、写入响应等。
- Event Demultiplexer:在Java NIO中对应的是Selector,它可以监控多个Channel上的事件,并在事件发生时通知Dispatcher。
总结来说,BIO、NIO与AIO的主要区别在于线程模型和阻塞行为上:
- BIO是一个连接一个线程,容易造成线程资源浪费,性能瓶颈明显。
- NIO在一个线程内可以管理多个连接,通过非阻塞方式减少无效等待时间,但程序需要自行轮询检查数据是否准备好。
- AIO则更进一步,由操作系统直接负责数据的读写操作,并在完成后通知应用,从而避免了不必要的上下文切换,理论上能提供最高的并发性能。
2.反射的原理,反射创建类实例的三种方式是什么。
反射是Java中的一项重要特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的各种属性和功能。
在运行时,Java反射机制可以加载类、获取类的信息(如类名、方法、字段等)、实例化对象以及调用方法等。
反射创建类实例的三种主要方式如下:
1. 通过无参构造函数创建:
// 假设我们有一个名为Book的类Class<?> bookClass = Class.forName("com.example.Book");Constructor<?> constructor = bookClass.getConstructor(); // 获取无参构造器Book book = (Book) constructor.newInstance(); // 调用无参构造器创建实例
2. 通过带参数的构造函数创建:
Class<?> bookClass = Class.forName("com.example.Book");Constructor<Book> constructor = bookClass.getDeclaredConstructor(String.class, String.class); // 获取带有String类型参数的私有构造器constructor.setAccessible(true); // 如果构造器是私有的,需要设置为可访问Book book = constructor.newInstance("The Title", "The Author"); // 使用指定参数创建实例
3. 通过Class的newInstance()方法创建:
// 注意:这种方式仅适用于具有默认(无参或public)构造函数的类Class<Book> bookClass = Book.class;try {Book book = bookClass.newInstance();} catch (InstantiationException | IllegalAccessException e) {// 处理异常,例如如果类是抽象类或者没有默认构造函数e.printStackTrace();}
上述代码展示了如何通过反射API动态地根据类信息创建类的实例。需要注意的是,对于非public的构造函数或其他成员,可能需要调用setAccessible(true)来绕过访问控制检查。
3.反射中,Class.forName 和 ClassLoader 区别 。
在Java反射机制中,Class.forName() 方法和 ClassLoader 类加载器都用于动态加载类,但它们之间存在一些区别:
1. Class.forName():
- 这是一个静态方法,位于 java.lang.Class 类中。
- 它接受一个字符串参数,该参数是完全限定类名(包括包名)。
- 当调用 Class.forName(className) 时,它会按照当前线程的上下文类加载器(context class loader)自动寻找并加载指定名称的类,并初始化该类。如果类还未被加载过,则执行类加载过程,包括验证、准备、解析和初始化阶段。
- 如果类中有静态初始化块或静态字段会被初始化。
- 通常抛出 ClassNotFoundException,如果找不到指定的类。
2. ClassLoader.loadClass() 或 ClassLoader.findSystemClass() 等相关方法:
- ClassLoader 是 Java 中用来加载类的抽象类,每个类在运行时都有一个与之关联的类加载器。
- 使用自定义的 ClassLoader 实例或者系统的默认类加载器,可以更灵活地控制类的加载过程,例如实现自己的类加载逻辑、支持热加载等高级功能。
- 调用如 ClassLoader.loadClass(className) 不会立即初始化类,仅完成类的加载过程,即验证、准备、解析阶段,而不会执行类的初始化(构造静态变量和执行静态初始化块)。
- 可以通过调用 Class.forName(className, initialize, classLoader) 来控制是否进行初始化操作,其中 initialize 参数为布尔值。
- 同样可能抛出 ClassNotFoundException。
总结来说,两者的主要区别在于:
- Class.forName() 默认情况下包含了完整的类加载和初始化过程,更加直观易用,常用于简单场景下的类加载。
- ClassLoader 提供了更底层和灵活的类加载能力,可以根据需要定制加载策略,且默认情况下不进行类的初始化。
4.描述动态代理的几种实现方式,分别说出相应的优缺点。
在Java中,动态代理有两种主要的实现方式:JDK动态代理和CGLIB代理。
1. JDK动态代理:
- 原理:基于Java反射机制实现。它通过InvocationHandler接口创建一个代理类,该代理类在运行时继承自Proxy类,并实现了与目标对象相同的接口。
- 优点:
- 由于是基于接口的,所以可以很方便地为一组具有相同接口的目标对象生成代理,适用范围广。
- 实现代理逻辑比较简单,只需要实现InvocationHandler接口即可。
- 不需要预先知道所有要代理的方法,代理逻辑更加灵活。
- 缺点:
- 需要目标类实现接口,对于没有接口的类无法进行代理。
- 由于使用了反射,在性能上相比于直接调用有一定损耗。
- 功能相对简单,不能针对类的成员变量进行操作。
2. CGLIB代理:
- 原理:基于ASM字节码生成框架,能够在运行期对字节码进行修改或动态生成新的类。CGLIB代理生成的代理类是被代理类的一个子类。
- 优点:
- 不依赖于接口,能够实现代理没有实现任何接口的目标类,适用性更广泛。
- 相比于JDK动态代理,CGLIB代理功能更加强大,可以拦截方法、修改方法等。
- 缺点:
- CGLIB代理会对类的所有方法进行增强,即使不希望增强的方法也会被代理,这可能造成额外的性能开销。
- 如果目标类做了final修饰或者有final方法,则无法进行代理。
- CGLIB库不是Java标准库的一部分,需要单独引入依赖。
- 字节码操作技术相比反射更为复杂,如果出现问题调试起来较为困难。
总结来说,JDK动态代理更适合接口较多且不需要对非接口方法进行增强的情况,而CGLIB代理则在不需要接口或需要对类的所有方法进行增强时更加适用。在实际应用中,如Spring框架会根据目标对象是否有接口智能选择使用哪种动态代理策略。
5.动态代理与 cglib 实现的区别。
JDK动态代理实现:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class JdkProxyExample {interface MyInterface {void doSomething();}static class TargetClass implements MyInterface {@Overridepublic void doSomething() {System.out.println("Target: Doing something...");}}static class LoggingInvocationHandler implements InvocationHandler {private final Object target;public LoggingInvocationHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("Before method call: " + method.getName());Object result = method.invoke(target, args);System.out.println("After method call: " + method.getName());return result;}public static MyInterface createLoggingProxy(TargetClass target) {return (MyInterface) Proxy.newProxyInstance(TargetClass.class.getClassLoader(),new Class<?>[]{MyInterface.class},new LoggingInvocationHandler(target));}}public static void main(String[] args) {MyInterface target = new TargetClass();MyInterface proxy = LoggingInvocationHandler.createLoggingProxy(new TargetClass());proxy.doSomething(); // 输出日志并调用目标方法}
}
在上述例子中,LoggingInvocationHandler实现了InvocationHandler接口,当代理对象的方法被调用时,会触发invoke方法,在该方法中添加了前后打印日志的逻辑,并实际调用了目标类的方法。
CGLIB代理实现:
首先需要引入CGLIB库(例如使用Spring框架中的CGLIB代理支持):
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class CglibProxyExample {static class TargetClass {public void doSomething() {System.out.println("Target: Doing something...");}}static class LoggingMethodInterceptor implements MethodInterceptor {@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println("Before method call: " + method.getName());Object result = proxy.invokeSuper(obj, args); // 调用父类(即目标类)的方法System.out.println("After method call: " + method.getName());return result;}public static TargetClass createLoggingProxy(TargetClass target) {Enhancer enhancer = new Enhancer();enhancer.setSuperclass(TargetClass.class);enhancer.setCallback(new LoggingMethodInterceptor());return (TargetClass) enhancer.create();}}public static void main(String[] args) {TargetClass target = new TargetClass();TargetClass proxy = LoggingMethodInterceptor.createLoggingProxy(new TargetClass());proxy.doSomething(); // 输出日志并调用目标方法}
}
在这个CGLIB代理的例子中,我们创建了一个LoggingMethodInterceptor类,它实现了MethodInterceptor接口。当代理对象的方法被调用时,会触发intercept方法,在这个方法里同样添加了日志输出,并通过MethodProxy调用了目标类的实际方法。CGLIB库通过字节码增强技术动态生成了继承自TargetClass的新类作为代理对象。
相关文章:
2024面试offer收割宝典字节篇
1.IO 模型有哪些,讲讲你理解的 nio ,他和 bio,aio 的区别是啥, 谈谈 reactor 模型。 IO 模型主要包括以下几种:1. 阻塞 I/O (BIO): 当一个线程调用 read() 或 write() 系统调用时,如果数据没有准备好或者缓冲区已满,则该线程会被操作系统阻塞,直到有数据可读或写入完…...
冒泡排序及其优化
冒泡排序 int[] arr {1,3,2,9,4,7,2,8};//比较多少轮(n个数字比较n-1次)for(int i0,n arr.length;i<n-1;i) {//每轮比较多少次(n-1-i次)for(int j 0;j<n-1-i;j) {//两两比较if(arr[j] > arr[j1]) { //比较结果为升序排列,如果想要降序排列结果将 >…...
【医学大模型 补全主诉】BioGPT + LSTM 自动补全医院紧急部门主诉
BioGPT LSTM 自动补全医院紧急部门主诉 问题:针对在紧急部门中自动补全主诉的问题子问题1: 提高主诉记录的准确性子问题2: 加快主诉记录的速度子问题3: 统一医疗术语的使用子问题4: 减少打字错误和误解子问题5: 提高非特定主诉的处理能力 解法数据预处理神经网络方…...
HCIE-Datacom证书有效期多久?HCIE考试有哪些内容?
如今越来越多的人开始关注并参与到华为认证的学习中来。 其中,华为认证数据通信专家(HCIE-Datacom)作为华为认证体系中的高级认证,备受瞩目。 那么,关于HCIE-Datacom证书的有效期以及HCIE考试的内容,你知道多少呢?下…...
OpenCV中的边缘检测技术及实现
边缘检测是在电脑如何理解图片这一问题中的一环,它帮助电脑找出照片里的轮廓和分界线。想象一下你在看一幅黑白漫画,轮廓线定义了每一个角色和物体,而电脑要做的,就是通过边缘检测来找出这些线条。这在很多像是图像分析这样的领域…...
机器学习基础(一)理解机器学习的本质
导读:在本文中,将深入探索机器学习的根本原理,包括基本概念、分类及如何通过构建预测模型来应用这些理论。 目录 机器学习 机器学习概念 相关概念 机器学习根本:模型 数据的语言:特征与标签 训练与测试…...
Eclipse - Makefile generation
Eclipse - Makefile generation References right mouse click on the project -> Properties -> C/C Build -> Generate Makefiles automatically 默认会在 Debug 目录下创建 Makefile 文件。 References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/...
Sora:新一代实时音视频通信框架
一、Sora简介 Sora是一个开源的实时音视频通信框架,旨在提供高效、稳定、可扩展的音视频通信解决方案。它基于WebRTC技术,支持跨平台、跨浏览器的实时音视频通信,并且具备低延迟、高并发、易集成等特点。 --点击进入Sora(一定要科学哦&#x…...
龟兔赛跑算法
一、题目 给定一个长度为 n1 的数组nums,数组中所有的数均在 1∼n1 的范围内,其中 n≥1。 请找出数组中任意一个重复的数。 样例 给定 nums [2, 3, 5, 4, 3, 2, 6, 7]。返回 2 或 3。 二、解析 解决这个问题的一种有效方法是使用快慢指针…...
Yii2项目使用composer异常记录
问题描述 在yii2项目中,使用require命令安装依赖时,出现如下错误提示 该提示意思是:composer运行时,执行了yiisoft/yii2-composer目录下的插件,但是该插件使用的API版本是1.0,但是当前的cmposer版本提供的…...
【蓝桥杯 2021】图像模糊
图像模糊 题目描述 小蓝有一张黑白图像,由 nm 个像素组成,其中从上到下共 n 行,每行从左到右 m 列。每个像素由一个 0 到 255 之间的灰度值表示。 现在,小蓝准备对图像进行模糊操作,操作的方法为: 对于…...
【leetcode】贪心算法介绍
详细且全面地分析贪心算法常用的解题套路、数据结构和代码逻辑如下: 找最值型: 每一步选择都是局部最优解,最后得到的结果就是全局最优解。常用于找零钱问题、区间覆盖问题等。一般情况下,可以通过排序将数据进行处理,…...
com.alibaba.fastjson.JSONException: toJSON error的原因
问题: 导出接口报错,显示json格式化异常 发现问题: 第一个参数为HttpResponse,转换成json的时候报错 修改方法: 1.调换两个参数的位置 2.在aop判断里边 把ServletAPI过滤掉 Before("excudeWebController()")pub…...
华为配置旁挂二层组网直接转发示例
配置旁挂二层组网直接转发示例 组网图形 图1 配置旁挂二层组网直接转发示例组网图 业务需求组网需求数据规划配置思路配置注意事项操作步骤配置文件扩展阅读 业务需求 企业用户通过WLAN接入网络,以满足移动办公的最基本需求。且在覆盖区域内移动发生漫游时ÿ…...
OLMo 以促进语言模型科学之名 —— OLMo Accelerating the Science of Language Models —— 全文翻译
OLMo: Accelerating the Science of Language Models OLMo 以促进语言模型科学之名 摘要 语言模型在自然语言处理的研究中和商业产品中已经变得无所不在。因为其商业上的重要性激增,所以,其中最强大的模型已经闭源,控制在专有接口之中&#…...
单例模式双端检测详解
正确写出doublecheck的单例模式_double check单例模式-CSDN博客...
秦PLUS荣耀版7.98万元起震撼上市,拉开“电比油低”大幕
2月19日,秦PLUS荣耀版正式上市,五大颠覆、三大焕新刷新A轿体验新高度。DM-i版本5款车型,官方指导价7.98万元——12.58万元;EV版本5款车型,官方指导价10.98万元——13.98万元。正式开启“电比油低”新时代。 电比油低&a…...
学习总结19
# 奶牛的耳语 ## 题目描述 在你的养牛场,所有的奶牛都养在一排呈直线的牛栏中。一共有 n 头奶牛,其中第 i 头牛在直线上所处的位置可以用一个整数坐标 pi(0< pi < 10^8) 来表示。在无聊的日子里,奶牛们常常在自己的牛栏里与其它奶牛交…...
rancher v2.8.1 如何成功注册已有 k8s 集群
需要加入的集群为rke2部署的双节点集群 $ kubectl get node NAME STATUS ROLES AGE VERSION rke-master01 Ready control-plane,etcd,master,worker 94d v1.26.8rke2r1 rke-master02 Ready control-plane,etcd,mast…...
Vue中$root的使用方法
查看本专栏目录 关于作者 还是大剑师兰特:曾是美国某知名大学计算机专业研究生,现为航空航海领域高级前端工程师;CSDN知名博主,GIS领域优质创作者,深耕openlayers、leaflet、mapbox、cesium,canvas&#x…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...
从面试角度回答Android中ContentProvider启动原理
Android中ContentProvider原理的面试角度解析,分为已启动和未启动两种场景: 一、ContentProvider已启动的情况 1. 核心流程 触发条件:当其他组件(如Activity、Service)通过ContentR…...
