一文学会Spring

embedded/2025/3/6 19:31:02/

一、Spring简介

Spring的优点

  1. Spring是一个开源免费的框架、容器
  2. Spring是一个轻量级的框架,非侵入式的
  3. 控制反转IOC、面向切面AOP
  4. 支持事务

Spring是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器

二、IOC

2.1 IOC本质

控制反转IOC,是一种设计思想,DI(依赖注入)是实现IOC的一种方式

通俗点来说就是原本你需要自己创建对象(new),现在交给Spring来管理。你只需要告诉Spring需要什么对象,Spring就会帮你创建并注入。

在这里插入图片描述

Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从IOC容器中取出需要的对象。

采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IOC容器,其实现方式是依赖注入(DI)

2.2 IOC创建对象方式

2.2.1 通过无参构造方法来创建

代码示例

1、创建user类

java">public class User {private String name;public User() {System.out.println("user无参构造方法");}public void setName(String name) {this.name = name;}public void show(){System.out.println("name="+ name );}
}

2、编辑beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="user" class="com.kuang.pojo.User"><property name="name" value="kuangshen"/></bean></beans>

3、测试类

java">ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
User user = (User) context.getBean("user");
user.show();

我们会发现在我们调用show()方法的时候,User对象已经通过无参构造初始化了。

注意:当我们的方法中没有无参构造方法会报错

在这里插入图片描述

2.2.2通过有参构造方法来创建

user类中添加有参构造方法

public User(String name) {this.name=name;
}

有参构造我们有三种方式来编写(在beans.xml中)

  1. 根据下标

    <bean id="user" class="com.kuang.pojo.User"><!-- index指构造方法 , 下标从0开始 --><constructor-arg index="0" value="kuangshen2"/>
    </bean>
    
  2. 根据参数名字

    <bean id="user" class="com.kuang.pojo.User"><!-- name指参数名 --><constructor-arg name="name" value="kuangshen2"/>
    </bean>
    
  3. 根据参数类型

    <bean id="user" class="com.kuang.pojo.User"><constructor-arg type="java.lang.String" value="kuangshen2"/>
    </bean>
    

三、Spring配置

3.1 别名

通过alias设置别名,为bean设置别名,可以设置多个别名

<alias name="user" alias="LTY"></alias>

3.2 Bean的配置

id:bean的唯一标识,相当于我们的对象名

class:bean对象所对应的全限定名

name:也是别名,可以同时取多个别名

3.3 import

一般用于团队开发使用,可以将两个或多个不同的配置文件,合并为一个配置文件

<import resource="beans.xml"/>
<import resource="beans1.xml"/>

四、依赖注入(DI)

依赖:指bean对象的创建依赖于容器

注入:指bean对象所依赖的资源,由容器来设置和装配

4.1 构造器注入

我们上面的案例就是构造器注入(构造器注入必须要有有参构造,可以没有无参构造)

4.2 set注入(重点)

要求被注入的属性,必须要有set方法

准备代码

java">public class Address {private String address;public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}
}
java">public class Student {private String name;private Address address;private String[] books;private List<String> hobbys;private Map<String,String> card;private Set<String> games;private String wife;private Properties info;public void setName(String name) {this.name = name;}public void setAddress(Address address) {this.address = address;}public void setBooks(String[] books) {this.books = books;}public void setHobbys(List<String> hobbys) {this.hobbys = hobbys;}public void setCard(Map<String, String> card) {this.card = card;}public void setGames(Set<String> games) {this.games = games;}public void setWife(String wife) {this.wife = wife;}public void setInfo(Properties info) {this.info = info;}public void show(){System.out.println("name="+ name+ ",address="+ address.getAddress()+ ",books=");for (String book:books){System.out.print("<<"+book+">>\t");}System.out.println("\n爱好:"+hobbys);System.out.println("card:"+card);System.out.println("games:"+games);System.out.println("wife:"+wife);System.out.println("info:"+info);}}
  1. 常量注入

     <bean id="student" class="com.kuang.pojo.Student"><property name="name" value="小明"/></bean>
    
  2. bean注入

     <bean id="addr" class="com.kuang.pojo.Address"><property name="address" value="重庆"/></bean><bean id="student" class="com.kuang.pojo.Student"><property name="name" value="小明"/><property name="address" ref="addr"/></bean>
    
  3. 数组注入

     <bean id="student" class="com.kuang.pojo.Student"><property name="name" value="小明"/><property name="address" ref="addr"/><property name="books"><array><value>西游记</value><value>红楼梦</value><value>水浒传</value></array></property></bean>
  4. List注入

     <property name="hobbys"><list><value>听歌</value><value>看电影</value><value>爬山</value></list></property>
    1234567
    
  5. Map注入

     <property name="card"><map><entry key="中国邮政" value="456456456465456"/><entry key="建设" value="1456682255511"/></map></property>
    123456
    
  6. set注入

     <property name="games"><set><value>LOL</value><value>BOB</value><value>COC</value></set></property>
    1234567
    
  7. Null注入

     <property name="wife"><null/></property>
    
  8. Properties注入

     <property name="info"><props><prop key="学号">20190604</prop><prop key="性别"></prop><prop key="姓名">小明</prop></props></property>
    

4.3 p命名和c命名

  1. P命名空间注入 : 需要在头文件中加入约束文件

    导入约束 : xmlns:p="http://www.springframework.org/schema/p"
    <!--P(属性: properties)命名空间 , 直接注入属性-->
    <bean id="user" class="com.kuang.pojo.User" p:name="狂神" p:age="18"/>
    
  2. c 命名空间注入 : 需要在头文件中加入约束文件

    导入约束 : xmlns:c="http://www.springframework.org/schema/c"
    <!--C(构造: Constructor)命名空间 , 使用构造器注入-->
    <bean id="user" class="com.kuang.pojo.User" c:name="狂神" c:age="18"/>
    

4.4 Bean的作用域

那些组成应用程序的主体及由Spring IOC容器所管理的对象,被称之为bean。

bean就是由IOC容器初始化、装配及管理的对象。

在这里插入图片描述

singleton(单例模式)

当一个bean的作用域为singleton时,那么Spring IOC容器只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则会返回bean的同一实例。

 <bean id="ServiceImpl" class="cn.csdn.service.ServiceImpl" scope="singleton">

测试

java">ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");User user = (User) context.getBean("user");User user2 = (User) context.getBean("user");System.out.println(user==user2);//返回true

Prototype(原型模式)

当一个bean的作用域为Prototype,表示一个bean定义对应多个对象实例。Prototype作用域的bean会导致在每次对该bean请求时都会创建一个新的bean实例。

 <bean id="account" class="com.foo.DefaultAccount" scope="prototype"/>  或者<bean id="account" class="com.foo.DefaultAccount" singleton="false"/>
Request

当一个bean的作用域为Request时,表示在一次HTTP请求中,一个bean定义对应一个实例;即每次HTTP请求都会有各自的bean实例,它们依据某个bean定义创建而成

 <bean id="loginAction" class=cn.csdn.LoginAction" scope="request"/>
Session

当一个bean的作用域为Session,表示在一个HTTP Session中,一个bean定义对应一个实例。

 <bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>

五、Bean的自动装配

Spring中bean有三种装配机制,分别是:

  1. 在xml中显示配置
  2. java中显示配置
  3. 隐式的bean发现机制和自动装配

Spring的自动装配需要从两个角度来实现,或者说是两个操作:

  1. 组件扫描:spring会自动发现应用上下文中所创建的bean
  2. 自动装配:soring自动满足bean之间的依赖,也就是我们说的IOC/DI

5.1 byName(按名称自动装配)

修改bean配置,增加一个属性autowire="byName"

<bean id="user" class="com.kuang.pojo.User" autowire="byName"><property name="str" value="qinjiang"/>
</bean>
  1. 将查找其类中所有的set方法名,例如setCat,获得将set去点并且首字母小写的字符串,即cat。
  2. spring容器中寻找是否有此字符串名称id的对象
  3. 如果有,就注入输出;如果没有,就报空指针异常

5.2 byType(按类型自动装配)

使用byType首先要保证:同一类型的对象,在spring容器中唯一;如果不唯一,会报异常。

<bean id="user" class="com.kuang.pojo.User" autowire="byType"><property name="str" value="qinjiang"/>
</bean>

5.3 使用注解

jdk1.5开始支持注解,spring2.5开始全面支持注解。

  1. spring配置文件中引入context文件头

    xmlns:context="http://www.springframework.org/schema/context"http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    
  2. 开启属性注解支持

    <context:annotation-config/>
    

@Autowired

  • @Autowired是按类型装配的,不支持id匹配
  • 需要导入spring-aop的包
java">public class User {@Autowiredprivate Cat cat;@Autowiredprivate Dog dog;private String str;public Cat getCat() {return cat;}public Dog getDog() {return dog;}public String getStr() {return str;}
}

@Qualifier

  • @Autowired是根据类型自动装配的,加上@Qualifier则可以根据byName的方式自动装配
  • @Qualifier不能单独使用
java">@Autowired
@Qualifier(value = "cat2")
private Cat cat;
@Autowired
@Qualifier(value = "dog2")
private Dog dog;
<bean id="dog1" class="com.kuang.pojo.Dog"/>
<bean id="dog2" class="com.kuang.pojo.Dog"/>
<bean id="cat1" class="com.kuang.pojo.Cat"/>
<bean id="cat2" class="com.kuang.pojo.Cat"/>

@Resourse

  • @Resource如果有指定的neme属性,先按该属性进行byName方式查找装配
  • 其次再进行默认的byName方式进行装配
  • 如果以上都不成功,则按byType进行装配
  • 都不成功,报异常
java">public class User {//如果允许对象为null,设置required = false,默认为true@Resource(name = "cat2")private Cat cat;@Resourceprivate Dog dog;private String str;
}
<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat1" class="com.kuang.pojo.Cat"/>
<bean id="cat2" class="com.kuang.pojo.Cat"/><bean id="user" class="com.kuang.pojo.User"/>

@Autowired与@Resource的区别

  1. @Autowired与@Resource都可以用来装配bean。都可以写在字段上,或写在setter方法上。
  2. @Autowired默认按类型装配(属于spring规范),默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如果想要使用名称装配可以结合@Qualifier注解进行使用。
  3. @Resource默认按名称装配,名称可以通过name属性进行指定。如果没有指定name属性,当注解写在字段上时,默认取字段名进行名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。

六、使用注解开发

spring4之后,想要使用注解形式,必须引入aop的包

在配置文件中,还要引入一个context约束

6.1 Bean的实现

@Component(“xxxx”)

  1. 配置扫描哪些包下的注解

    <!--指定注解扫描包-->
    <context:component-scan base-package="com.kuang.pojo"/>
    
  2. 在指定包下编写类。增加注解

    java">@Component("user")
    // 相当于配置文件中 <bean id="user" class="当前注解的类"/>
    public class User {public String name = "秦疆";
    }
    

6.2 属性注入

@value

  1. 可以不用提供set方法,直接在对象名上添加@value(“值”)

    java">@Component("user")
    // 相当于配置文件中 <bean id="user" class="当前注解的类"/>
    public class User {@Value("秦疆")// 相当于配置文件中 <property name="name" value="秦疆"/>public String name;
    }
    
  2. 如果提供了set方法,在set方法上添加@value(“值”)

    java">@Component("user")
    public class User {public String name;@Value("秦疆")public void setName(String name) {this.name = name;}
    }
    

6.3 衍生注解

@Component三个衍生注解

为了更好的进行分层,spring可以使用其他三个注解,功能一样。

  • @Controller:controller层
  • @Service:service层
  • @Repository:dao层

6.4 作用域

@scope

  • singleton:默认的,spring会采用单例模式创建这个对象。关闭工程,所有对象都会销毁
  • prototype:多例模式。关闭工厂,所有对象不会销毁。内部的垃圾回收机制会回收。
java">@Controller("user")
@Scope("prototype")
public class User {@Value("秦疆")public String name;
}

6.4 小结

XML与注解比较

  • XML可以使用任何场景,结构清晰,维护方便
  • 注解不是自己提供的类使用不了,开发简单方便

XML与注解整合开发(推荐):

  • xml管理bean

  • 注解完成属性注入

  • 使用过程中,可以不用扫描,扫描是为了类上的注解

    <context:annotation-config/>  
    

七、基于Java类进行配置

@Configuration

  1. 新建一个config配置包,编写一个MyConfig配置类

    java">@Configuration  //代表这是一个配置类
    public class MyConfig {@Bean //通过方法注册一个bean,这里的返回值就Bean的类型,方法名就是bean的id!public Dog dog(){return new Dog();}}
    

导入其他配置如何做呢?

@Import

  1. 我们再编写一个配置类

    java">@Configuration  //代表这是一个配置类
    public class MyConfig2 {
    }
    
  2. 再之前的配置类中我们来选择导入这个配置类

    java">@Configuration
    @Import(MyConfig2.class)  //导入合并其他配置类,类似于配置文件中的 inculde 标签
    public class MyConfig {@Beanpublic Dog dog(){return new Dog();}}
    

八、代理模式

8.1 静态代理

静态代理角色分析

  • 抽象角色:一般使用接口或者抽象类来实现
  • 真实角色:被代理的角色
  • 代理角色:代理真实角色;代理真实角色后,一般会做一些附属的操作
  • 客户:使用代理角色来进行一些操作

静态代理模式的核心思想

  • 代理与正式角色实现同一接口
  • 代理持有真实角色的引用
  • 代理增强角色

代码实现

Rent . java 即抽象角色

//抽象角色:租房
public interface Rent {public void rent();
}
1234

Host . java 即真实角色

//真实角色: 房东,房东要出租房子
public class Host implements Rent{public void rent() {System.out.println("房屋出租");}
}
123456

Proxy . java 即代理角色

//代理角色:中介
public class Proxy implements Rent {private Host host;public Proxy() { }public Proxy(Host host) {this.host = host;}//租房public void rent(){seeHouse();host.rent();fare();}//看房public void seeHouse(){System.out.println("带房客看房");}//收中介费public void fare(){System.out.println("收中介费");}
}
123456789101112131415161718192021222324

Client . java 即客户

//客户类,一般客户都会去找代理!
public class Client {public static void main(String[] args) {//房东要租房Host host = new Host();//中介帮助房东Proxy proxy = new Proxy(host);//你去找中介!proxy.rent();}
}

分析:真实角色只需关注核心业务,代理角色负责增强功能

静态代理的好处优缺点

优点

  • 可以使得我们的真实角色更加纯粹,不再去关注一些公共的事情
  • 公共的业务由代理来完成,实现了业务的分工
  • 公共业务发生扩展时变得更加集中和方便.

缺点

  • 类多了,多了代理类,工作量变大

8.2 动态代理

动态代理的核心思想是通过反射机制接口实现,在程序运行期间动态创建代理对象。

动态代理的角色和静态代理的一样

动态代理的代理类时动态生成的 静态代理的代理类是我们提前写好的

动态代理分为两类:一类是基于接口动态代理,一类是基于类的动态代理

  • 基于接口的动态代理–JDK动态代理
  • 基于类的动态代理–cglib
  • 现在用的比较多的是javasist来生成动态代理

JDK动态代理

代理对象会拦截所有接口方法的调用,并将其委托给InvocationHandlerinvoke 方法

动态代理的核心是方法调用的拦截和转发

java">//万能公式
public class ProxyInvocationHandler implements InvocationHandler {private Object target;public void setTarget(Object target) {this.target = target;}//生成代理类public Object getProxy(){return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);}// proxy : 代理类// method : 代理类的调用处理程序的方法对象.public Object invoke(Object proxy, Method method, Object[] args) throwsThrowable {log(method.getName());Object result = method.invoke(target, args);return result;}public void log(String methodName){System.out.println("执行了"+methodName+"方法");}}

测试

java">public class Test {public static void main(String[] args) {//真实对象UserServiceImpl userService = new UserServiceImpl();//代理对象的调用处理程序ProxyInvocationHandler pih = new ProxyInvocationHandler();pih.setTarget(userService); //设置要代理的对象UserService proxy = (UserService)pih.getProxy(); //动态生成代理类!proxy.delete();}
}

九、AOP

AOP就是面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。

spring_860">9.1 AOP在spring中的作用

AOP核心概念

  1. 横切关注点(Cross-Cutting Concerns):多个模块中重复出现的、与核心业务无关的功能

  2. 切面(Aspect):封装横切关注点的模块,包含通知(Advice)切点(Pointcut)

  3. 连接点(Join Point):程序执行过程中可以插入切点的面,例如方法调用、异常抛出等

  4. 切点(Pointcut):通过表达式匹配一组连接点,确定在哪些地方通知

    示例:execution(* com.example.service.*.*(..)) 匹配 service 包下所有类的所有方法。

  5. 通知(Advice):切面在特定连接点执行的动作

    img

9.2 使用Spring实现AOP

重点:使用AOP,需要导入一个依赖包

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version>
</dependency>

9.2.1 通过Spring API实现

首先编写我们的业务接口和实现类

java">public interface UserService {public void add();public void delete();public void update();public void search();}
public class UserServiceImpl implements UserService{@Overridepublic void add() {System.out.println("增加用户");}@Overridepublic void delete() {System.out.println("删除用户");}@Overridepublic void update() {System.out.println("更新用户");}@Overridepublic void search() {System.out.println("查询用户");}
}

然后去写我们的增强类 , 我们编写两个 , 一个前置增强 一个后置增强

java">public class Log implements MethodBeforeAdvice {//method : 要执行的目标对象的方法//objects : 被调用的方法的参数//Object : 目标对象@Overridepublic void before(Method method, Object[] objects, Object o) throws Throwable {System.out.println( o.getClass().getName() + "的" + method.getName() + "方法被执行了");}
}
public class AfterLog implements AfterReturningAdvice {//returnValue 返回值//method被调用的方法//args 被调用的方法的对象的参数//target 被调用的目标对象@Overridepublic void afterReturning(Object returnValue, Method method, Object[] args,Object target) throws Throwable {System.out.println("执行了" + target.getClass().getName()+"的"+method.getName()+"方法,"+"返回值:"+returnValue);}
}
12345678910111213141516171819202122

最后去spring的文件中注册 , 并实现aop切入实现 , 注意导入约束

java"><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!--注册bean--><bean id="userService" class="com.kuang.service.UserServiceImpl"/><bean id="log" class="com.kuang.log.Log"/><bean id="afterLog" class="com.kuang.log.AfterLog"/><!--aop的配置--><aop:config><!--切入点 expression:表达式匹配要执行的方法--><aop:pointcut id="pointcut" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/><!--执行环绕; advice-ref执行方法 . pointcut-ref切入点--><aop:advisor advice-ref="log" pointcut-ref="pointcut"/><aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/></aop:config></beans>

测试

java">public class MyTest {@Testpublic void test(){ApplicationContext context = newClassPathXmlApplicationContext("beans.xml");UserService userService = (UserService) context.getBean("userService");userService.search();}
}

9.2.2 自定义类来实现AOP

第一步 : 写我们自己的一个切入类

java">public class DiyPointcut {public void before(){System.out.println("---------方法执行前---------");}public void after(){System.out.println("---------方法执行后---------");}}

spring中配置

java"><!--第二种方式自定义实现-->
<!--注册bean-->
<bean id="diy" class="com.kuang.config.DiyPointcut"/><!--aop的配置-->
<aop:config><!--第二种方式:使用AOP的标签实现--><aop:aspect ref="diy"><aop:pointcut id="diyPonitcut" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/><aop:before pointcut-ref="diyPonitcut" method="before"/><aop:after pointcut-ref="diyPonitcut" method="after"/></aop:aspect>
</aop:config>

测试:

java">public class MyTest {@Testpublic void test(){ApplicationContext context = newClassPathXmlApplicationContext("beans.xml");UserService userService = (UserService) context.getBean("userService");userService.add();}
}

9.2.3 使用注解实现

第一步:编写一个注解实现的增强类

java">package com.kuang.config;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;@Aspect
public class AnnotationPointcut {@Before("execution(* com.kuang.service.UserServiceImpl.*(..))")public void before(){System.out.println("---------方法执行前---------");}@After("execution(* com.kuang.service.UserServiceImpl.*(..))")public void after(){System.out.println("---------方法执行后---------");}@Around("execution(* com.kuang.service.UserServiceImpl.*(..))")public void around(ProceedingJoinPoint jp) throws Throwable {System.out.println("环绕前");System.out.println("签名:"+jp.getSignature());//执行目标方法proceedObject proceed = jp.proceed();System.out.println("环绕后");System.out.println(proceed);}
}

第二步:在Spring配置文件中,注册bean,并增加支持注解的配置

java"><!--第三种方式:注解实现-->
<bean id="annotationPointcut" class="com.kuang.config.AnnotationPointcut"/>
<aop:aspectj-autoproxy/>


http://www.ppmy.cn/embedded/170547.html

相关文章

windows 利用nvm 管理node.js 2025最新版

1.首先在下载nvm 下载链接 2. 下载最新版本的nvm 3. 同意协议 注意&#xff1a;选择安装路径 之后一直下一步即可 可以取消勾选 open with Powershell 勾选后它会自动打开Powershell 这里选用cmd 输入以下命令查看是否安装成功 nvm version 查看已经安装的版本 我之前自…

Golang依赖注入实战:从容器管理到应用实践

#作者&#xff1a;曹付江 文章目录 1、示例&#xff1a; 管理依赖关系的容器1.1. 日志记录器设置1.2. 数据库连接设置1.3. 管理依赖关系的容器 2、如何使用容器3、结论 依赖注入&#xff08;DI&#xff09;是一种在软件应用程序中促进松散耦合和可测试性的设计模式。它允许将依…

基于HTML的贪吃蛇小游戏

一、前言 “贪吃蛇”是一款经典的休闲益智游戏&#xff0c;其玩法简单但极具挑战性。玩家需要控制一条不断移动的蛇&#xff0c;通过吃掉食物来增长身体长度&#xff0c;同时避免撞到墙壁或自己的身体。游戏的核心机制包括蛇的移动、食物的生成以及碰撞检测等。 二、起源 贪吃…

SCI期刊推荐 | 免版面费 | 计算机领域:信息系统、软件工程、自动化和控制

在学术研究领域&#xff0c;选择合适的SCI期刊对科研成果的传播与认可至关重要。了解SCI期刊的研究领域和方向是基础&#xff0c;确保投稿内容与期刊主题相符。同时&#xff0c;要关注期刊的影响因子和评估标准&#xff0c;选择具有较高影响力和学术认可度的期刊。阅读期刊的投…

【手撕算法】支持向量机(SVM)从入门到实战:数学推导与核技巧揭秘

摘要 支持向量机&#xff08;SVM&#xff09;是机器学习中的经典算法&#xff01;本文将深入解析最大间隔分类原理&#xff0c;手撕对偶问题推导过程&#xff0c;并实战实现非线性分类与图像识别。文中附《统计学习公式手册》及SVM调参指南&#xff0c;助力你掌握这一核心算法…

Kotlin 扩展函数

Kotlin 扩展函数是一种强大的功能&#xff0c;它允许你为现有的类添加新的函数&#xff0c;而不需要修改原始类的代码。这意味着你可以为任何类添加方法&#xff0c;即使你没有访问该类的源代码。这对于创建通用工具函数、简化代码和提高可读性非常有用。 如何定义扩展函数 扩…

T-SQL 语言基础: SQL 数据库对象元数据及配置信息获取

目录 介绍目录视图 获取表和架构名称获取列信息 信息架构视图 获取表信息获取列信息 系统存储过程和函数 获取对象列表获取对象详细信息获取约束信息获取数据库属性信息 总结引用 介绍 在 SQL 数据库管理中&#xff0c;获取数据库对象的元数据信息是至关重要的。元数据提供了…

数据结构:八大排序(冒泡,堆,插入,选择,希尔,快排,归并,计数)详解

目录 一.冒泡排序 二.堆排序 三.插入排序 四.选择排序 五.希尔排序 六.快速排序 1.Lomuto版本&#xff08;前后指针法&#xff09; 2.Lomuto版本的非递归算法 3.hoare版本&#xff08;左右指针法&#xff09; 4.挖坑法找分界值&#xff1a; 七.归并排序 八.计数排序…