java理解

springboot

打包

mvn install:install-file -Dfile=<path-to-jar> -DgroupId=<group-id> -DartifactId=<artifact-id> -Dversion=<version> -Dpackaging=jar
<path-to-jar> 是你的 JAR 文件的路径。
<group-id> 是你的项目的组 ID。
<artifact-id> 是你的项目的构件 ID。
<version> 是你的项目的版本号。mvn install:install-file -Dfile=D:\ojdbc6-11.2.0.1.0.jar -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=11.2.0.1.0 -Dpackaging=jar

AOP

根据目标对象是否实现接口自动选择动态代理机制。

  • JDK 动态代理:适用于目标对象实现了接口的情况。

    JDK 动态代理是 Java 提供的一种动态创建代理对象的机制。它允许在运行时动态地创建一个代理类,该代理类实现了与目标对象相同的接口,并且可以拦截对目标对象方法的调用。通过这种方式,可以在不修改目标对象代码的情况下,对目标对象的方法调用进行增强(如添加日志、事务管理等)。

  • CGLIB 动态代理:适用于目标对象没有实现接口的情况。

通过aspect注解定义切面,可以结合自定义注解实现 不改变源代码情况下,在方法执行前后增加功能。

IOC

通过 IoC,Spring 容器负责管理对象的生命周期和依赖关系,而不是由开发者手动管理。

  • @Repository:标记一个类为数据访问层组件,通常用于数据库操作。
  • @Qualifier:用于指定注入的 Bean 的名称,当存在多个同类型的 Bean 时,可以使用该注解来明确指定注入哪一个 Bean。
  • @Primary:用于指定默认注入的 Bean,当存在多个同类型的 Bean 时,Spring 容器会优先注入标记为 @Primary 的 Bean。
  • @Cacheable` 是 Spring 缓存框架提供的一个注解,用于声明一个方法的结果是可缓存的。当方法被调用时,Spring 会检查缓存中是否已经存在相应的值。如果存在,则直接从缓存中返回结果,而不会执行方法体;如果不存在,则执行方法体并将结果存入缓存,以便下次调用时可以直接从缓存中获取。
  • @Transactional: 被标记的方法如果出现**RuntimeExceptionError**会回滚事物。
    1. Spring 事务的隔离级别有哪些?
      • READ_UNCOMMITTED:最低的隔离级别,允许读取未提交的数据,可能出现脏读。
      • READ_COMMITTED:允许读取已提交的数据,避免了脏读,但可能出现不可重复读。
      • REPEATABLE_READ(默认级别):保证在同一个事务中多次读取数据的结果是一致的,避免了不可重复读,但可能出现幻读。
      • SERIALIZABLE:最高的隔离级别,完全隔离并发事务,避免了脏读、不可重复读和幻读,但性能开销最大。
    2. 什么是脏读、不可重复读和幻读?
      • 脏读:一个事务读取了另一个事务未提交的数据。
      • 不可重复读:一个事务在两次读取同一数据时,数据被另一个事务修改,导致两次读取的结果不一致。
      • 幻读:一个事务在两次读取同一范围的数据时,数据被另一个事务插入或删除,导致两次读取的结果不一致。

线程池

线程池的基本概念

  1. 什么是线程池?
    • 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建了线程后,从队列中取出任务并执行。
    • 线程池的主要目的是减少线程创建和销毁的开销,提高线程的复用性。
  2. 线程池的主要优点是什么?
    • 减少线程创建和销毁的开销:线程池会复用已创建的线程,减少线程创建和销毁的次数。
    • 提高响应速度:任务提交后可以直接从线程池中获取线程执行,减少了线程创建的时间。
    • 提高线程的可管理性:线程池可以对线程进行统一管理,如设置线程的最大数量、队列大小等。
    • 避免资源耗尽:通过限制线程的最大数量,避免系统资源耗尽。
  3. 线程池的主要组成部分是什么?
    • 线程池管理器:负责创建和管理线程池。
    • 工作线程:线程池中实际执行任务的线程。
    • 任务队列:用于存储待执行任务的队列。
    • 任务接口:所有任务必须实现的接口,以便工作线程可以执行。

线程池的实现原理

  1. Java 中的线程池是如何实现的?
    • Java 的线程池主要通过 java.util.concurrent 包中的 Executor 框架实现。
    • Executor 是一个接口,定义了执行任务的方法。
    • ExecutorServiceExecutor 的子接口,提供了更丰富的功能,如线程池的管理。
    • ThreadPoolExecutorExecutorService 的实现类,提供了线程池的核心实现。
  2. ThreadPoolExecutor 的构造参数有哪些?
    • corePoolSize:核心线程数,线程池中始终保持的线程数量。
    • maximumPoolSize:最大线程数,线程池中允许的最大线程数量。
    • keepAliveTime:非核心线程的空闲存活时间。
    • unitkeepAliveTime 的时间单位。
    • workQueue:任务队列,用于存储待执行任务的队列。
    • threadFactory:线程工厂,用于创建线程。
    • handler:拒绝策略,当任务队列满且线程数达到最大值时,如何处理新任务。
  3. 线程池的拒绝策略有哪些?
    • AbortPolicy:直接抛出 RejectedExecutionException
    • CallerRunsPolicy:由调用线程执行任务。
    • DiscardPolicy:直接丢弃任务。
    • DiscardOldestPolicy:丢弃队列中最老的任务,然后尝试提交新任务。

线程池的使用方法

  1. 如何创建一个线程池?

    • 使用 ThreadPoolExecutor 的构造方法创建线程池。

    • 示例:

      import java.util.concurrent.*;public class ThreadPoolExample {public static void main(String[] args) {ThreadPoolExecutor executor = new ThreadPoolExecutor(2, // 核心线程数4, // 最大线程数60L, // 空闲存活时间TimeUnit.SECONDS, // 时间单位new LinkedBlockingQueue<Runnable>(100) // 任务队列);for (int i = 0; i < 10; i++) {executor.execute(() -> {System.out.println("Task executed by: " + Thread.currentThread().getName());});}executor.shutdown();}
      }
      
  2. 如何关闭线程池?

    • 使用 shutdown() 方法关闭线程池,等待所有任务完成。
    • 使用 shutdownNow() 方法立即关闭线程池,尝试中断正在执行的任务。
  3. 如何提交任务到线程池?

    • 使用 execute(Runnable command) 方法提交任务。
    • 使用 submit(Callable<T> task) 方法提交任务并返回 Future 对象。

线程池的性能优化

  1. 如何优化线程池的性能?
    • 合理设置线程池大小:根据系统的硬件资源和任务类型,合理设置核心线程数和最大线程数。
    • 选择合适的任务队列:根据任务的特点选择合适的任务队列,如 LinkedBlockingQueueArrayBlockingQueue
    • 设置合理的拒绝策略:根据业务需求选择合适的拒绝策略,避免任务丢失。
    • 监控线程池状态:通过 ThreadPoolExecutor 提供的方法监控线程池的状态,如 getActiveCount()getCompletedTaskCount() 等。

线程池的高级特性

  1. 什么是线程池的饱和策略?

    • 当任务队列满且线程数达到最大值时,线程池会采取的策略。可以通过 RejectedExecutionHandler 接口自定义饱和策略。
  2. 如何自定义线程工厂?

    • 实现 ThreadFactory 接口,自定义线程的创建逻辑。

    • 示例:

      import java.util.concurrent.*;public class CustomThreadFactory implements ThreadFactory {private final String threadNamePrefix;public CustomThreadFactory(String threadNamePrefix) {this.threadNamePrefix = threadNamePrefix;}@Overridepublic Thread newThread(Runnable r) {return new Thread(r, threadNamePrefix + "-Thread-" + Thread.currentThread().getId());}public static void main(String[] args) {ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100),new CustomThreadFactory("MyCustomThread"));for (int i = 0; i < 10; i++) {executor.execute(() -> {System.out.println("Task executed by: " + Thread.currentThread().getName());});}executor.shutdown();}
      }
      

线程池的常见问题

  1. 线程池中的线程是如何复用的?
    • 线程池中的线程在执行完一个任务后,会返回线程池,等待下一个任务。如果线程池中的线程数量超过核心线程数且空闲时间超过 keepAliveTime,则会销毁多余的线程。
  2. 线程池中的线程是如何销毁的?
    • 当线程池中的线程数量超过核心线程数且空闲时间超过 keepAliveTime 时,多余的线程会被销毁。
    • 当调用 shutdown() 方法时,线程池会等待所有任务完成后再销毁所有线程。
    • 当调用 shutdownNow() 方法时,线程池会尝试中断正在执行的任务,并立即销毁所有线程。
  3. 线程池中的任务是如何调度的?
    • 线程池中的任务通过任务队列进行调度。任务队列可以是阻塞队列(如 LinkedBlockingQueueArrayBlockingQueue)或非阻塞队列(如 SynchronousQueue)。
    • 线程池会从任务队列中取出任务并分配给空闲的线程执行。

线程池的监控

  1. 如何监控线程池的状态?
    • 使用 ThreadPoolExecutor 提供的方法监控线程池的状态,如:
      • getActiveCount():获取当前活跃的线程数。
      • getCompletedTaskCount():获取已完成的任务数。
      • getTaskCount():获取任务总数。
      • getPoolSize():获取线程池中的线程数。
      • getLargestPoolSize():获取线程池中曾经出现的最大线程数。

设计模式

装饰器加适配器

理解:

准备一个接口,两个实现类,实现类一实现基本功能,实现类二中将实现类一注入进去,调用实现类一的方法,在方法前后添加特殊逻辑。

应用场景:

流程里用不用适配器,就看一点:各环节接口对不上,但又得一起干活。 对不上(参数、格式、方法名不一样),又改不了其中一方,就用适配器当“翻译”;能对上,或者能直接改接口,就不用折腾。

示例:

public interface ZSQservice {String ZSQService(String arg0, String arg1);
}
@Service
public class ZSQserviceImpl implements ZSQservice {@Overridepublic String ZSQService(String arg0, String arg1) {System.out.println("ZSQservice impl, arg0=" + arg0 + ", arg1=" + arg1);return "return, arg0=" + arg0 + ", arg1=" + arg1;}
}
@Slf4j
@Service
public class ZSQLOGIMPL implements ZSQservice {private ZSQservice zsqservice;public ZSQLOGIMPL(@Qualifier("ZSQEncryImpl")ZSQservice zsqservice) {this.zsqservice = zsqservice;}@Overridepublic String ZSQService(String arg0, String arg1) {log.info("执行前记录参数 arg0=" + arg0 + ", arg1=" + arg1);String returnJson = zsqservice.ZSQService(arg0, arg1);log.info("执行后记录结果 "+returnJson);return returnJson;}
}
@Slf4j
@Service
public class ZSQEncryImpl implements ZSQservice {private ZSQservice zsqservice;public ZSQEncryImpl(@Qualifier("ZSQserviceImpl") ZSQservice zsqservice) {this.zsqservice = zsqservice;}@Overridepublic String ZSQService(String arg0, String arg1) {log.info("数据加密中");String json = zsqservice.ZSQService(arg0, arg1);log.info("数据加密完成");return json;}
}
  @Testvoid zsqTest(){ZSQservice zsQservice = new ZSQLOGIMPL(new ZSQEncryImpl(new ZSQserviceImpl()));zsQservice.ZSQService("1","2");}
: 执行前记录参数 arg0=1, arg1=2
: 数据加密中ZSQservice impl, arg0=1, arg1=2
: 数据加密完成
: 执行后记录结果 return, arg0=1, arg1=2

代理模式

只要装饰器模式不添加特定功能就是代理,也可以看aop是spring自动进行代理的。

AOP加自定义注解

示例:

1. 添加依赖

pom.xml 中添加 Spring AOP 的依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2. 自定义注解

2.1 @LogAction

作用:记录方法的执行日志,包括方法名、入参和出参。
属性

  • action:描述日志内容,可选,默认值为 "日志记录"
package com.example.annotation;import java.lang.annotation.*;@Target({ElementType.METHOD, ElementType.TYPE})  // 可以标注在方法或类上
@Retention(RetentionPolicy.RUNTIME)  // 运行时保留
public @interface LogAction {String action() default "日志记录";  // 默认值
}

3. 自定义注解例子

3.1 @LogAction 示例
package com.example.service;import com.example.annotation.LogAction;
import org.springframework.stereotype.Service;

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图论核心算法详解:从存储结构到最短路径(附C++实现)

目录 一、图的基础概念与术语 二、图的存储结构 1. 邻接矩阵 实现思路&#xff1a; 2. 邻接表 实现思路&#xff1a; 应用场景&#xff1a; 时间复杂度分析&#xff1a; 三、图的遍历算法 1. 广度优先搜索&#xff08;BFS&#xff09; 核心思想&#xff1a; 应用场…

力扣top100(day03-02)--图论

本文为力扣TOP100刷题笔记 笔者根据数据结构理论加上最近刷题整理了一套 数据结构理论加常用方法以下为该文章&#xff1a; 力扣外传之数据结构&#xff08;一篇文章搞定数据结构&#xff09; 200. 岛屿数量 class Solution {// DFS辅助方法&#xff0c;用于标记和"淹没&q…

建造者模式:从“参数地狱”到优雅构建

深夜&#xff0c;一条紧急告警刺穿寂静&#xff1a;核心报表服务因NullPointerException全线崩溃。排查根源&#xff0c;罪魁祸首竟是一个拥有10多个参数的“上帝构造函数”。本文将从这个灾难现场出发&#xff0c;引入“链式建造者模式”进行重构&#xff0c;并深入Spring AI、…

jenkins在windows配置sshpass

我的服务器里jenkins是通过docker安装的&#xff0c;jenkins与项目都部署在同一台服务器上还好&#xff0c;但是当需要通过jenkins构建&#xff0c;再通过scp远程推送到别的服务器上&#xff0c;就出问题了&#xff0c;毕竟不是手动执行scp命令&#xff0c;可以手动输入密码&am…

Linux操作系统从入门到实战(十八)在Linux里面怎么查看进程

Linux操作系统从入门到实战&#xff08;十八&#xff09;在Linux里面怎么查看进程前言一、如何识别一个进程&#xff1f;—— PID二、怎么查看进程的信息&#xff1f;方式1&#xff1a;通过/proc目录方式2&#xff1a;用ps命令三、父进程是什么&#xff1f;—— PPID四、bash是…

[TryHackMe](知识学习)---基于堆栈得到缓冲区溢出

1.了解缓冲区溢出WINDOWS程序动态调试工具immunity debuggerhttps://www.immunityinc.com/products/debugger/2.Mona脚本#!/usr/bin/env python3import socket, time, sysip "10.201.99.37"port 1337 timeout 5 prefix "OVERFLOW1 "string prefix &q…

LRU算法与LFU算法

知识点&#xff1a; LRU是Least Recently Used的缩写&#xff0c;意思是最近最少使用&#xff0c;它是一种Cache替换算法 Cache的容量有限&#xff0c;因此当Cache的容量用完后&#xff0c;而又有新的内容需要添加进来时&#xff0c; 就需要挑选 并舍弃原有的部分内容&#xf…

目标检测公开数据集全解析:从经典到前沿

目标检测公开数据集全解析&#xff1a;从经典到前沿 一、引言 目标检测&#xff08;Object Detection&#xff09;是计算机视觉领域的核心任务之一&#xff0c;旨在在图像或视频中识别并定位感兴趣的物体。与图像分类不同&#xff0c;目标检测不仅需要判断物体的类别&#xf…

数据备份与进程管理

一、数据备份1.Linux服务器中需要备份的数据&#xff08;1&#xff09;Linux系统重要数据&#xff1a;/root/目录&#xff0c;/home/目录&#xff0c;/etc/目录&#xff08;2&#xff09;安装服务的数据&#xff1a;Apache&#xff08;配置文件&#xff0c;网页主目录&#xff…

docker volume卷入门教程

1. 基础概念 Docker卷是专门用于持久化容器数据的存储方案&#xff0c;独立于容器生命周期。其核心优势包括&#xff1a; 数据持久化&#xff1a;容器删除后数据仍保留跨容器共享&#xff1a;多个容器可访问同一卷备份与迁移&#xff1a;支持直接复制卷数据驱动支持&#xff1a…

计算机网络——协议

1. 计算机网络分层1.1 OSI 7层模型应用层表示层会话层传输层网络层数据链路层物理层1.2 TCP/IP 4 层模型应用层运输层网际层网络接口层1.3 5层体系机构应用层传输层网络层数据链路层物理层2. 应用层协议2.1 HTTP协议2.1.1 基本介绍HTTP&#xff08;HyperText Transfer Protocol…

【React】hooks 中的闭包陷阱

在 React Hooks 中的 闭包陷阱&#xff08;Closure Trap&#xff09;在 useEffect、事件回调、定时器等场景里很常见。1. 闭包陷阱是什么 当你在函数组件里定义一个回调&#xff08;比如事件处理函数&#xff09;&#xff0c;这个回调会捕获当时渲染时的变量值。如果后面状态更…

校园快递小程序(腾讯地图API、二维码识别、Echarts图形化分析)

&#x1f388;系统亮点&#xff1a;腾讯地图API、二维码识别、Echarts图形化分析&#xff1b;一.系统开发工具与环境搭建1.系统设计开发工具后端使用Java编程语言的Spring boot框架 项目架构&#xff1a;B/S架构 运行环境&#xff1a;win10/win11、jdk17小程序&#xff1a; 技术…

Python网络爬虫(二) - 解析静态网页

文章目录一、网页解析技术介绍二、Beautiful Soup库1. Beautiful Soup库介绍2. Beautiful Soup库几种解析器比较3. 安装Beautiful Soup库3.1 安装 Beautiful Soup 43.2 安装解析器4. Beautiful Soup使用步骤4.1 创建Beautiful Soup对象4.2 获取标签4.2.1 通过标签名获取4.2.2 通…

【Linux基础知识系列】第九十四篇 - 如何使用traceroute命令追踪路由

在网络环境中&#xff0c;了解数据包从源主机到目标主机的路径是非常重要的。这不仅可以帮助我们分析网络连接问题&#xff0c;还可以用于诊断网络延迟、丢包等问题。traceroute命令是一个强大的工具&#xff0c;它能够追踪数据包在网络中的路径&#xff0c;显示每一跳的延迟和…

达梦数据闪回查询-快速恢复表

Time:2025/08/12Author:skatexg一、环境说明DM数据库&#xff1a;DM8.0及以上版本二、适用场景研发在误操作或变更数据后&#xff0c;想马上恢复表到某个时间点&#xff0c;可以通过闪回查询功能快速实现&#xff08;通过全量备份恢复时间长&#xff0c;成本高&#xff09;三、…

力扣(LeetCode) ——225 用队列实现栈(C语言)

题目&#xff1a;用队列实现栈示例1&#xff1a; 输入&#xff1a; [“MyStack”, “push”, “push”, “top”, “pop”, “empty”] [[], [1], [2], [], [], []] 输出&#xff1a; [null, null, null, 2, 2, false] 解释&#xff1a; MyStack myStack new MyStack(); mySta…

微软推出AI恶意软件检测智能体 Project Ire

开篇 在8月5号&#xff0c;微软研究院发布了一篇博客文章&#xff0c;在该篇博客中推出了一款名为Project Ire的AI Agent。该Agent可以在无需人类协助的情况下&#xff0c;自主分析和分类二进制文件。它可以在无需了解二进制文件来源或用途的情况下&#xff0c;对文件进行完全的…

哪些对会交由SpringBoot容器管理?

在 Spring Boot 中,交由容器管理的对象通常称为“Spring Bean”,这些对象的创建、依赖注入、生命周期等由 Spring 容器统一管控。以下是常见的会被 Spring Boot 容器管理的对象类型及识别方式: 一、通过注解声明的组件(最常见) Spring Boot 通过类级别的注解自动扫描并注…

Android POS应用在android运行常见问题及解决方案

概述 本文档记录了在Android POS应用开发过程中遇到的两个关键问题及其解决方案&#xff1a; UnsatisfiedLinkError: couldnt find "libnative.so" 错误ActivityNotFoundException 错误商户信息一致性检查绕过 问题1&#xff1a;UnsatisfiedLinkError - libnative.so…