当前位置: 首页 > news >正文

Spring Security简介

前面我们已经完成了传智健康后台管理系统的部分功能,例如检查项管理、检查组管理、套餐管理、预
约设置等。接下来我们需要思考2个问题:
问题1:在生产环境下我们如果不登录后台系统就可以完成这些功能操作吗?
答案显然是否定的,要操作这些功能必须首先登录到系统才可以。
问题2:是不是所有用户,只要登录成功就都可以操作所有功能呢?
答案是否定的,并不是所有的用户都可以操作这些功能。不同的用户可能拥有不同的权限,这就需要进
行授权了。
认证:系统提供的用于识别用户身份的功能,通常提供用户名和密码进行登录其实就是在进行认证,认
证的目的是让系统知道你是谁。
授权:用户认证成功后,需要为用户授权,其实就是指定当前用户可以操作哪些功能。
本章节就是要对后台系统进行权限控制,其本质就是对用户进行认证和授权。
3.2 权限模块数据模型
前面已经分析了认证和授权的概念,要实现最终的权限控制,需要有一套表结构支撑:
用户表t_user、权限表t_permission、角色表t_role、菜单表t_menu、用户角色关系表t_user_role、角
色权限关系表t_role_permission、角色菜单关系表t_role_menu。
表之间关系如下图:
在这里插入图片描述
通过上图可以看到,权限模块共涉及到7张表。在这7张表中,角色表起到了至关重要的作用,其处于核心位置,因为用户、权限、菜单都和角色是多对多关系。

接下来我们可以分析一下在认证和授权过程中分别会使用到哪些表:

认证过程:只需要用户表就可以了,在用户登录时可以查询用户表t_user进行校验,判断用户输入的用户名和密码是否正确。

授权过程:用户必须完成认证之后才可以进行授权,首先可以根据用户查询其角色,再根据角色查询对应的菜单,这样就确定了用户能够看到哪些菜单。然后再根据用户的角色查询对应的权限,这样就确定了用户拥有哪些权限。所以授权过程会用到上面7张表。

3.3 Spring Security简介

Spring Security是 Spring提供的安全认证服务的框架。 使用Spring Security可以帮助我们来简化认证和授权的过程。官网:https://spring.io/projects/spring-security

在这里插入图片描述

对应的maven坐标:

<dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-web</artifactId><version>5.0.5.RELEASE</version>
</dependency>
<dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-config</artifactId><version>5.0.5.RELEASE</version>
</dependency>

常用的权限框架除了Spring Security,还有Apache的shiro框架。

3.4 Spring Security入门案例

3.4.1 工程搭建

创建maven工程,打包方式为war,为了方便起见我们可以让入门案例工程依赖health_interface,这样相关的依赖都继承过来了。

pom.xml

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.itheima</groupId><artifactId>springsecuritydemo</artifactId><version>1.0-SNAPSHOT</version><packaging>war</packaging><name>springsecuritydemo Maven Webapp</name><url>http://www.example.com</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><dependencies><dependency><groupId>com.itheima</groupId><artifactId>health_interface</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><configuration><!-- 指定端口 --><port>85</port><!-- 请求路径 --><path>/</path></configuration></plugin></plugins></build>
</project>

提供index.html页面,内容为hello Spring Security!!

3.4.2 配置web.xml
在web.xml中主要配置SpringMVC的DispatcherServlet和用于整合第三方框架的DelegatingFilterProxy,用于整合Spring Security。

<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>Archetype Created Web Application</display-name><filter><!--DelegatingFilterProxy用于整合第三方框架整合Spring Security时过滤器的名称必须为springSecurityFilterChain,否则会抛出NoSuchBeanDefinitionException异常--><filter-name>springSecurityFilterChain</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class></filter><filter-mapping><filter-name>springSecurityFilterChain</filter-name><url-pattern>/*</url-pattern></filter-mapping><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!-- 指定加载的配置文件 ,通过参数contextConfigLocation加载 --><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-security.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>*.do</url-pattern></servlet-mapping></web-app>

3.4.3 配置spring-security.xml
在spring-security.xml中主要配置Spring Security的拦截规则和认证管理器。

<?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:context="http://www.springframework.org/schema/context"xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:security="http://www.springframework.org/schema/security"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/securityhttp://www.springframework.org/schema/security/spring-security.xsd"><!--http:用于定义相关权限控制auto-config:是否自动配置设置为true时框架会提供默认的一些配置,例如提供默认的登录页面、登出处理等设置为false时需要显示提供登录表单配置,否则会报错use-expressions:用于指定intercept-url中的access属性是否使用表达式--><security:http auto-config="true" use-expressions="true"><!--intercept-url:定义一个拦截规则pattern:对哪些url进行权限控制access:在请求对应的URL时需要什么权限,默认配置时它应该是一个以逗号分隔的角色列表,请求的用户只需拥有其中的一个角色就能成功访问对应的URL--><security:intercept-url pattern="/**"  access="hasRole('ROLE_ADMIN')" /></security:http><!--authentication-manager:认证管理器,用于处理认证操作--><security:authentication-manager><!--authentication-provider:认证提供者,执行具体的认证逻辑--><security:authentication-provider><!--user-service:用于获取用户信息,提供给authentication-provider进行认证--><security:user-service><!--user:定义用户信息,可以指定用户名、密码、角色,后期可以改为从数据库查询用户信息{noop}:表示当前使用的密码为明文--><security:user name="admin" password="{noop}admin" authorities="ROLE_ADMIN"></security:user></security:user-service></security:authentication-provider></security:authentication-manager>
</beans>

3.5 对入门案例改进

前面我们已经完成了Spring Security的入门案例,通过入门案例我们可以看到,Spring Security将我们项目中的所有资源都保护了起来,要访问这些资源必须要完成认证而且需要具有ROLE_ADMIN角色。

但是入门案例中的使用方法离我们真实生产环境还差很远,还存在如下一些问题:

1、项目中我们将所有的资源(所有请求URL)都保护起来,实际环境下往往有一些资源不需要认证也可以访问,也就是可以匿名访问。

2、登录页面是由框架生成的,而我们的项目往往会使用自己的登录页面。

3、直接将用户名和密码配置在了配置文件中,而真实生产环境下的用户名和密码往往保存在数据库中。

4、在配置文件中配置的密码使用明文,这非常不安全,而真实生产环境下密码需要进行加密。

本章节需要对这些问题进行改进。

3.5.1 配置可匿名访问的资源

第一步:在项目中创建pages目录,在pages目录中创建a.html和b.html

第二步:在spring-security.xml文件中配置,指定哪些资源可以匿名访问

<!--http:用于定义相关权限控制指定哪些资源不需要进行权限校验,可以使用通配符
-->
<security:http security="none" pattern="/pages/a.html" />
<security:http security="none" pattern="/paegs/b.html" />
<security:http security="none" pattern="/pages/**"></security:http>

通过上面的配置可以发现,pages目录下的文件可以在没有认证的情况下任意访问。

3.5.2 使用指定的登录页面
第一步:提供login.html作为项目的登录页面

<html>
<head><title>登录</title>
</head>
<body><form action="/login.do" method="post">username:<input type="text" name="username"><br>password:<input type="password" name="password"><br><input type="submit" value="submit"></form>
</body>
</html>

第二步:修改spring-security.xml文件,指定login.html页面可以匿名访问

<security:http security="none" pattern="/login.html" />
第三步:修改spring-security.xml文件,加入表单登录信息的配置<!--form-login:定义表单登录信息
-->
<security:form-login login-page="/login.html"username-parameter="username"password-parameter="password"login-processing-url="/login.do"default-target-url="/index.html"authentication-failure-url="/login.html"/>

第四步:修改spring-security.xml文件,关闭CsrfFilter过滤器

<!--csrf:对应CsrfFilter过滤器disabled:是否启用CsrfFilter过滤器,如果使用自定义登录页面需要关闭此项,否则登录操作会被禁用(403)
-->
<security:csrf disabled="true"></security:csrf>

3.5.3 从数据库查询用户信息
如果我们要从数据库动态查询用户信息,就必须按照spring security框架的要求提供一个实现UserDetailsService接口的实现类,并按照框架的要求进行配置即可。框架会自动调用实现类中的方法并自动进行密码校验。

实现类代码:

package com.itheima.security;import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class UserService implements UserDetailsService {//模拟数据库中的用户数据public  static  Map<String, com.itheima.pojo.User> map = new HashMap<>();static {com.itheima.pojo.User user1 = new com.itheima.pojo.User();user1.setUsername("admin");user1.setPassword("admin");com.itheima.pojo.User user2 = new com.itheima.pojo.User();user2.setUsername("xiaoming");user2.setPassword("1234");
​map.put(user1.getUsername(),user1);map.put(user2.getUsername(),user2);}/*** 根据用户名加载用户信息* @param username* @return* @throws UsernameNotFoundException*/public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {System.out.println("username:" + username);com.itheima.pojo.User userInDb = map.get(username);//模拟根据用户名查询数据库if(userInDb == null){//根据用户名没有查询到用户return null;}//模拟数据库中的密码,后期需要查询数据库String passwordInDb = "{noop}" + userInDb.getPassword();List<GrantedAuthority> list = new ArrayList<>();//授权,后期需要改为查询数据库动态获得用户拥有的权限和角色list.add(new SimpleGrantedAuthority("add"));list.add(new SimpleGrantedAuthority("delete"));list.add(new SimpleGrantedAuthority("ROLE_ADMIN"));UserDetails user = new User(username,passwordInDb,list);return user;}
}

spring-security.xml:

<!--authentication-manager:认证管理器,用于处理认证操作
-->
<security:authentication-manager><!--authentication-provider:认证提供者,执行具体的认证逻辑--><security:authentication-provider user-service-ref="userService"></security:authentication-provider>
</security:authentication-manager>



本章节我们提供了UserService实现类,并且按照框架的要求实现了UserDetailsService接口。在spring配置文件中注册UserService,指定其作为认证过程中根据用户名查询用户信息的处理类。当我们进行登录操作时,spring security框架会调用UserService的loadUserByUsername方法查询用户信息,并根据此方法中提供的密码和用户页面输入的密码进行比对来实现认证操作。

3.5.4 对密码进行加密
前面我们使用的密码都是明文的,这是非常不安全的。一般情况下用户的密码需要进行加密后再保存到数据库中。

常见的密码加密方式有:

3DES、AES、DES:使用对称加密算法,可以通过解密来还原出原始密码

MD5、SHA1:使用单向HASH算法,无法通过计算还原出原始密码,但是可以建立彩虹表进行查表破解

bcrypt:将salt随机并混入最终加密后的密码,验证时也无需单独提供之前的salt,从而无需单独处理salt问题

加密后的格式一般为:

$2a101010/bTVvqqlH9UiE0ZJZ7N2Me3RIgUCdgMheyTgV0B4cMCSokPa.6oCa
加密后字符串的长度为固定的60位。其中:$是分割符,无意义;2a是bcrypt加密版本号;10是cost的值;而后的前22位是salt值;再然后的字符串就是密码的密文了。

实现步骤:

第一步:在spring-security.xml文件中指定密码加密对象

<!--配置密码加密对象-->
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" /><!--认证管理器,用于处理认证操作-->
<security:authentication-manager><!--认证提供者,执行具体的认证逻辑--><security:authentication-provider user-service-ref="userService"><!--指定密码加密策略--><security:password-encoder ref="passwordEncoder" /></security:authentication-provider>
</security:authentication-manager>
<!--开启spring注解使用-->
<context:annotation-config></context:annotation-config>

第二步:修改UserService实现类

package com.itheima.security;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class UserService implements UserDetailsService {@Autowiredprivate BCryptPasswordEncoder passwordEncoder;public  Map<String, com.itheima.pojo.User> map = new HashMap<>();//模拟数据库中的用户数据public void initData(){com.itheima.pojo.User user1 = new com.itheima.pojo.User();user1.setUsername("admin");user1.setPassword(passwordEncoder.encode("admin"));com.itheima.pojo.User user2 = new com.itheima.pojo.User();user2.setUsername("xiaoming");user2.setPassword(passwordEncoder.encode("1234"));
​map.put(user1.getUsername(),user1);map.put(user2.getUsername(),user2);}/*** 根据用户名加载用户信息* @param username* @return* @throws UsernameNotFoundException*/public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {initData();System.out.println("username:" + username);com.itheima.pojo.User userInDb = map.get(username);//模拟根据用户名查询数据库if(userInDb == null){//根据用户名没有查询到用户return null;}String passwordInDb = userInDb.getPassword();//模拟数据库中的密码,后期需要查询数据库List<GrantedAuthority> list = new ArrayList<>();//授权,后期需要改为查询数据库动态获得用户拥有的权限和角色list.add(new SimpleGrantedAuthority("add"));list.add(new SimpleGrantedAuthority("delete"));list.add(new SimpleGrantedAuthority("ROLE_ADMIN"));UserDetails user = new User(username,passwordInDb,list);return user;}
}

3.5.5 配置多种校验规则
为了测试方便,首先在项目中创建a.html、b.html、c.html、d.html几个页面

修改spring-security.xml文件:

<!--只要认证通过就可以访问-->
<security:intercept-url pattern="/index.jsp"  access="isAuthenticated()" />
<security:intercept-url pattern="/a.html"  access="isAuthenticated()" /><!--拥有add权限就可以访问b.html页面-->
<security:intercept-url pattern="/b.html"  access="hasAuthority('add')" /><!--拥有ROLE_ADMIN角色就可以访问c.html页面-->
<security:intercept-url pattern="/c.html"  access="hasRole('ROLE_ADMIN')" /><!--拥有ROLE_ADMIN角色就可以访问d.html页面,注意:此处虽然写的是ADMIN角色,框架会自动加上前缀ROLE_-->
<security:intercept-url pattern="/d.html"  access="hasRole('ADMIN')" />

3.5.6 注解方式权限控制
Spring Security除了可以在配置文件中配置权限校验规则,还可以使用注解方式控制类中方法的调用。例如Controller中的某个方法要求必须具有某个权限才可以访问,此时就可以使用Spring Security框架提供的注解方式进行控制。

实现步骤:

第一步:在spring-security.xml文件中配置组件扫描,用于扫描Controller

<mvc:annotation-driven></mvc:annotation-driven>
<context:component-scan base-package="com.itheima.controller"></context:component-scan>

第二步:在spring-security.xml文件中开启权限注解支持

<!--开启注解方式权限控制-->
<security:global-method-security pre-post-annotations="enabled" />

第三步:创建Controller类并在Controller的方法上加入注解进行权限控制

package com.itheima.controller;import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;@RestController
@RequestMapping("/hello")
public class HelloController {@RequestMapping("/add")@PreAuthorize("hasAuthority('add')")//表示用户必须拥有add权限才能调用当前方法public String add(){System.out.println("add...");return "success";}@RequestMapping("/delete")@PreAuthorize("hasRole('ROLE_ADMIN')")//表示用户必须拥有ROLE_ADMIN角色才能调用当前方法public String delete(){System.out.println("delete...");return "success";}
}

3.5.7 退出登录
用户完成登录后Spring Security框架会记录当前用户认证状态为已认证状态,即表示用户登录成功了。那用户如何退出登录呢?我们可以在spring-security.xml文件中进行如下配置:

<!--logout:退出登录logout-url:退出登录操作对应的请求路径logout-success-url:退出登录后的跳转页面
-->
<security:logout logout-url="/logout.do" logout-success-url="/login.html" invalidate-session="true"/>

通过上面的配置可以发现,如果用户要退出登录,只需要请求/logout.do这个URL地址就可以,同时会将当前session失效,最后页面会跳转到login.html页面。

相关文章:

Spring Security简介

前面我们已经完成了传智健康后台管理系统的部分功能&#xff0c;例如检查项管理、检查组管理、套餐管理、预 约设置等。接下来我们需要思考2个问题&#xff1a; 问题1&#xff1a;在生产环境下我们如果不登录后台系统就可以完成这些功能操作吗&#xff1f; 答案显然是否定的&am…...

Hadoop安装 --- 简易安装Hadoop

目录 1、使用xftp工具 在opt目录下创建install和soft文件 2、使用xftp工具 将压缩包上传到install文件 3、编写shell脚本 3.1、创建目录来放shell脚本 3.2、创建autoinsatll.sh文件并修改权限 3.3、编写autoinsatll.sh 文件 刷新资源 运行文件 格式化 启动所有进程 Ha…...

俞军产品方法论,消化吸收,要点整理

一、总体概括二、产品经理、价值、用户模型、交易模型三、价值、产品和企业的价值生存游戏的常见要点&#xff1a;企业做产品的4方面产出&#xff1a;四、决策五、俞军产品方法论&#xff0c;认知迭代史1&#xff09;俞军12条产品军规2)产品经理职级的背后影响因素&#xff1a;…...

spring注解的开端(@Component替代bean标签的使用)

目录 一、介绍 1.什么是注解开发&#xff1f; 2.Spring注解的版本 3.基于spring注解的应用 4. Component的细分注解 5.相关注解 二、简单例子讲解 1.类打注解 2.扫描注解放入工厂 3.总工厂取注解调用 4.运行结果 总结&#xff1a; 一、介绍 1.什么是注解开发&…...

Matlab傅里叶谱方法求解一维波动方程

傅里叶谱方法求解基本偏微分方程—一维波动方程 一维波动方程 对于一根两端固定、没有受到任何外力的弦, 若只研究其中的一段, 在不太长的时间 里, 固定端来不及对这段弦产生影响, 则可以认为固定端是不存在的, 弦的长度为无限大。 这种无界 (−∞<x<∞)(-\infty<x&…...

py3中 collections.Counter()函数典型例题

文章目录py3中 collections 的常用STL**Counter()** 函数**defaultdict()** 函数**deque()** 函数**orderedDict()** 函数&#xff08;缺例题&#xff09;小结py3中 collections 的常用STL 对于这个工具包非常好用&#xff0c;尤其是其中的 Counter() 函数 使用次数颇为频繁&a…...

Linux部署达梦数据库超详细教程

陈老老老板&#x1f9b8;&#x1f468;‍&#x1f4bb;本文专栏&#xff1a;国产数据库-达梦数据库&#x1f468;‍&#x1f4bb;本文简述&#xff1a;本文讲一下达梦数据库的下载与安装教程&#xff08;Linux版&#xff09;&#xff0c;超级详细。&#x1f468;‍&#x1f4bb…...

ctfshow 每周大挑战 极限命令执行

《简单的命令执行题目》 这里感叹一下&#xff0c;g4佬是真好厉害&#xff0c;这次题目十分的难&#xff0c;嗯&#xff0c;对我这种菜鸡来说是这样的&#xff0c;想了一天&#xff0c;最后结束了&#xff0c;也还是没有想明白第五题的解法&#xff0c;我真是fw&#xff0c;到最…...

使用vue3,vite,less,flask,python从零开始学习硅谷外卖(16-40集)

严正声明&#xff01; 重要的事情说一遍&#xff0c;本文章仅供分享&#xff0c;文章和代码都是开源的&#xff0c;严禁以此牟利&#xff0c;严禁侵犯尚硅谷原作视频的任何权益&#xff0c;我知道学习编程的人各种各样的心思都有&#xff0c;但这不是你对开源社区侵权的理由&am…...

坚持就是胜利

很多朋友&#xff0c;可能坚持了多年的同等学力申硕考试&#xff0c;依然没有通过。如果你感到困惑&#xff0c;感到迷茫&#xff0c;要坚信&#xff1a;坚持就能胜利。有很多人跟你一样&#xff0c;一直坚持在路上&#xff0c;没有停止脚步。 生活没有你想象的那么好&#xff…...

代码中出现转置 pose (c2w,外参矩阵) 或者转置 intrinsic (内参)矩阵的原因

在代码中见到 pose&#xff08;c2w&#xff09;&#xff0c;intrinsic 矩阵的转置&#xff0c;觉得比较奇怪。 后来想了一下为什么。下面解释一下&#xff1a; 用 c2w 矩阵举例子。理论上&#xff0c;一个 c2w 左乘上 一个相机坐标系下的点 P的坐标&#xff0c;能够得到该点在…...

2023 年腾讯云服务器配置价格表出炉(2核2G/2核4G/4核8G/8核16G、16核32G)

腾讯云轻量应用服务器为轻量级的云服务器&#xff0c;使用门槛低&#xff0c;按套餐形式购买&#xff0c;轻量应用服务器套餐自带的公网带宽较大&#xff0c;4M、6M、7M、10M、14M及20M套餐可选&#xff0c;如果是云服务器CVM这个带宽价格就要贵很多了。 1、轻量应用服务器优惠…...

相机出图画面一半清晰,一半模糊的原因是什么?

1、问题背景&#xff1a;在做项目的过程中&#xff0c;有遇到过几次&#xff0c;出图后画面是一半清晰&#xff0c;一半模糊的现象&#xff0c;再重新对焦也是一样。但换了个镜头后就好了&#xff0c;这应该是镜头的质量问题&#xff0c;但导致镜头出现这种问题的具体原因是什么…...

Rust学习入门--【4】Rust 输出到命令行

Rust 语言中的打印“函数” 学习新的编程语言时&#xff0c;大家都喜欢打印“Hello World”。 在Rust中怎样将字符串打印出来呢&#xff1f; Rust 输出文字的方式主要有两种&#xff1a;println!() 和 print!()。 “函数”差异说明&#xff1a; 这两个"函数"都是向…...

Vector刷写方案—vFlash工具介绍

我是穿拖鞋的汉子,魔都中坚持长期主义的工科男! 今天魔都天气是连阴雨,滴滴答答的下个不停,心情也跟着潮湿起来!老规矩分享一段喜欢的文字,避免成为高知识低文化的工程师: 即使在真正的困境里,也一直提示自己,每次自恋不得超过十分钟! 那些看似无法度过得困境,不是…...

【阶段总结】《非结构化信息分析应用与实践(筹)》

《非结构化信息分析应用与实践&#xff08;筹&#xff09;》Part 1.知识储备一、机器学习 1.几种常见的有监督学习算法 2.几种常见的无监督学习算法 3.数据挖掘基础知识 30 问 二、神经网络与深度学习 1.MP神经网络模型&#xff08;附实例代码讲解&#xff09; 2.图解LST…...

七大设计原则之迪米特法则应用

目录1 迪米特法则介绍2 迪米特法则应用1 迪米特法则介绍 迪米特原则&#xff08;Law of Demeter LoD&#xff09;是指一个对象应该对其他对象保持最少的了解&#xff0c;又叫最少知 道原则&#xff08;Least Knowledge Principle,LKP&#xff09;&#xff0c;尽量降低类与类之…...

curl命令用法精简整理

目录1.GET请求1.1 形式1&#xff1a;1.2 形式2&#xff1a;2.POST请求2.1 无入参&#xff1a;2.2 form传参&#xff08;文件&#xff09;&#xff1a;2.3 json入参&#xff1a;2.4 json文件入参&#xff1a;3.请求计时3.1 time命令&#xff08;Linux&#xff09;&#xff1a;3.…...

Fluent Python 笔记 第 5 章 一等函数

在 Python 中&#xff0c;函数是一等对象。编程语言理论家把“一等对象”定义为满足下述条件的程 序实体: 在运行时创建能赋值给变量或数据结构中的元素 • 能作为参数传给函数能作为函数的返回结果 5.1 把函数视作对象 会用 map。 5.2 高阶函数 接受函数为参数&#xff0…...

卡尔曼滤波器与DSP实现

卡尔曼滤波器是利用系统状态方程&#xff0c;结合测量结果对系统状态进行进行最优估计的算法。本文介绍它的主要公式&#xff0c;并举例在C6000 DSP上实现。 推荐资料 KalmanFilter.NETUnderstanding Kalman Filters卡尔曼滤波与组合导航原理 “If you can’t explain it sim…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

MySQL:分区的基本使用

目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区&#xff08;Partitioning&#xff09;是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分&#xff08;分区&#xff09;可以独立存储、管理和优化&#xff0c;…...

MySQL 主从同步异常处理

阅读原文&#xff1a;https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主&#xff0c;遇到的这个错误&#xff1a; Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一&#xff0c;通常表示&#xff…...

绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化

iOS 应用的发布流程一直是开发链路中最“苹果味”的环节&#xff1a;强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说&#xff0c;这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发&#xff08;例如 Flutter、React Na…...

前端调试HTTP状态码

1xx&#xff08;信息类状态码&#xff09; 这类状态码表示临时响应&#xff0c;需要客户端继续处理请求。 100 Continue 服务器已收到请求的初始部分&#xff0c;客户端应继续发送剩余部分。 2xx&#xff08;成功类状态码&#xff09; 表示请求已成功被服务器接收、理解并处…...