没有合适的资源?快使用搜索试试~ 我知道了~
java面试知识点积累
需积分: 0 0 下载量 164 浏览量
2024-11-03
11:17:40
上传
评论
收藏 2.9MB DOCX 举报
温馨提示
java面试知识点积累
资源推荐
资源详情
资源评论
Java 知识积累
一、反射
反射是指将类的各个组成部分封装成对象。每一个.java 文件定义了至少一个类,这个类
可以包括成员变量、构造方法和成员方法三个模块的内容。将.java 文件编译为.class 字
节码文件的过程中,实际上是通过一个类加载器将.java 文件中的类转换为一个类名为
Class 的类的对象,该对相有三个数组:
成员变量数组:Field[] fields
构造方法 Construction[] cons
成员方法 Methos[] methods
获取字节码文件中 Class 对象的三种方式:
(1) Class.forName(“全类名”)//全类名包括类的路径
例如:Class cls1 = Class.forName(“cn.itcast.domain.Person”)
(2) 类名的 class
Class cls2 = Person.class;//Person 是个自定义类
(3) 对象.getClass()
Person p = new Person();
Class cls3 = p.getClass();
反射是框架设计的灵魂,框架是半成品软件,可以在框架的基础上进行软件开发。
二、springboot 的 ioc 和 aop 机制
2.1 控制反转 ioc
ioc(控制反转):能实现模块之间、类之间的解耦合。Ioc 把对象的创建、赋值、管理工
作都交给代码之外的容器实现,也就是对象的创建是由外部资源完成的,由容器代替开
发人员管理对象。
2.2 面向切面编程 aop
Spring 的 AOP(Aspect-Oriented Programming)是面向切面编程的缩写,是 Spring 框架中的一个重要内容。以下是对 AOP
及其相关概念的解释:
2.2.1 Spring AOP 的基本概念
Spring AOP 是一种编程范式,旨在将系统的关注点(如日志、事务管理、安全控制等)分离到单独的模块中,称为切面
(Aspect)。这些切面定义了如何在程序执行的某些点插入横切逻辑。通过这种方式,Spring AOP 帮助开发者更好地组织和维
护代码,降低耦合度,提高可重用性和开发效率。它特别适用于那些具有横切逻辑的应用场合,如性能监测、事务管理、安全
控制和日志记录等。
2.2.2 连接点(JoinPoint)
连接点是程序执行中的某个点,如方法调用或异常抛出等。在 Spring AOP 中,连接点通常指的是方法级别的执行点。这些点
是可以被 AOP 框架进行增强的位置。需要注意的是,Spring AOP 仅支持方法类型的连接点。
2.2.3 切面(Aspect)
切面是一个关注点的模块,通常由一组切入点和通知组成。它定义了如何在程序执行的某些点插入横切逻辑。切面是 AOP 的
核心概念之一,它使得开发者能够将横切关注点从业务逻辑中分离出来,从而提高了代码的可维护性和复用性。
2.2.4 织入(Weaving)
织入是将切面中的增强逻辑应用到目标对象上的过程。在 Spring AOP 中,织入通常是在运行期通过动态代理实现的。这意味
着,当目标对象的方法被调用时,Spring AOP 框架会自动将切面中的增强逻辑应用到该方法上。
2.2.5 环绕增强(Around Advice)
环绕增强是 AOP 联盟定义的一种增强类型,它表示在目标方法执行前后同时实施增强。在环绕增强中,开发者可以定义在目
标方法执行前、执行后以及是否继续执行目标方法的逻辑。这使得环绕增强具有极大的灵活性,可以用来实现复杂的横切逻
辑。
综上所述,Spring AOP 通过连接点、切面、织入和环绕增强等概念,为开发者提供了一种强大的编程范式,使得横切关注点可
以从业务逻辑中分离出来,从而提高了代码的可维护性和复用性。
三、动态代理
动态代理是指在程序运行期间,创建目标对象的代理对象,并对目标对象中的方法进行
功能性增强的一种技术,在生成代理对象的过程中,目标对象不变,代理对象中的方法
对目标对象的方法的增强方法,可以理解为在运行期间,对象中的方法的动态拦截,在
拦截方法的前后执行功能操作。有了动态代理技术,那么就可以在不修改方法代码的情
况下,增强被代理对象的方法的功能。
Object proxyInstance = Proxy.newProxyInstance(obj.getClass().getClassLoader()
, obj.getClass().getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//方法执行前
long startTime = System.currentTimeMillis();
Object result = method.invoke(obj, args);//执行方法的调用
//方法执行后
long endTime = System.currentTimeMillis();
SimpleDateFormat sdf = new SimpleDateFormat();
System.out.printf(String.format("%s 方法执行结束时间:%%s ;方法执行耗时:%%d%%n"
, method.getName()), sdf.format(endTime), endTime - startTime);
return result;
}
});
return proxyInstance;
}
四、线程的同步和异步
线程同步:同步要求线程必须按照一定的顺序执行,一个线程必须等待另一个线程完成
某一任务再执行。当一个线程在等待另一个线程完成某一任务时,线程进入阻塞状态,
直到等待的任务完成。同步操作有利于保证数据的完整性和一致性,因为线程之间有明
确的执行顺序,避免了数据竞争和条件竞争。但同步会导致性能瓶颈,因为线程必须等
待其他线程完成,这就限制了并发性。
线程异步:异步操作允许线程并发执行,一个线程不需要等待另一个线程完成即可执行
自己的任务。异步操作可能导致数据竞争和条件竞争,为了保证数据的一致性和完整性,
可以采用同步机制(包括信号量、锁)来确保数据的一致性和完整性。异步机制可以提
高性能,因为线程可以并发执行,充分利用多处理核的优势。
线程死锁的四个必要条件:
互斥、不剥夺、循环等待、请求与保持
五、java 创建线程的几种方式
java 使用 Thread 类代表线程,所有线程对象都必须是 Thread 类或者其子类的实例。Java
可以用以下 5 种方式来创建线程。
(1)继承 Thread 类创建线程,重写 run()方法,run()方法中是程序员想要线程执行的操作。
使用 start()方法开启线程,开启之后线程会自动执行重写的 run()方法。注意不要 new 了一
个线程后直接调用 run()方法,这样只调用了一个方法而没有开启一个线程。
(2) 实现 Runnable 接口创建线程。
(3) 实现 Callable 接口和 Future 接口方式实现。
补充:Java 的 CountDownLatch 类
通过使用 CountDownLatch 可以使当前线程阻塞,等待其他线程完成给定任务。
主要应用场景是一个线程等待多个线程完成给定任务后,然后执行后续的操作
的场景。
CountDownLatch 的构造函数接受一个 int 类型的参数作为计数器,构造方法如
下:
public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
}
当 我 们 调 用 CountDownLatch 的 countDown() 方 法 时 , N 就 会 减 1 ,
CountDownLatch 的 await() 方 法 会 阻 塞 当 前 进 程 , 直 到 计 数 器 变 成 0.
CountDownLatch 的 getCount()方法返回当前计数。
实例:
public class DownLoadWorker implements Runnable{
private String url;
private CountDownLatch countDownLatch;
public DownLoadWorker(String url, CountDownLatch countDownLatch) {
this.url = url;
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
//省略无数业务代码
System.out.println("线程" + Thread.currentThread().getName() + "开始
下载完成");
countDownLatch.countDown();
}
}
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch=new CountDownLatch(5);
//使用 Stream 生成 5 个线程
List<Thread> workers = Stream
.generate(() -> new Thread(new DownLoadWorker("https://image.
baidu.com/", countDownLatch)))
.limit(5)
.collect(toList());
//运行线程
workers.forEach(Thread::start);
//等待线程完成
countDownLatch.await();
System.out.println("图片已下载完~~~");
}
(1) Thread 本质上是实现了 Runnable 接口的一个实例。
使用 start()方法开启线程,开启之后线程会自动执行重写的 run()方法。
剩余17页未读,继续阅读
资源评论
微扬嘴角
- 粉丝: 224
- 资源: 2
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功